Лекция 2 курса «Методы автоматизации тестирования» - davaiknam.ru o_O
Главная
Поиск по ключевым словам:
страница 1
Похожие работы
Название работы Кол-во страниц Размер
Лекция 1 курса «Методы автоматизации тестирования» 1 139.21kb.
Реферат Данная работа посвящена разработке программного обеспечения... 1 43.11kb.
Лекция методы прогнозирования и планирования план Система методов... 1 129.75kb.
Лекция 3 Педагогический тест. План лекции. История педагогического... 1 166.19kb.
Лекция «Историческая социология» М. Рожанский 20. 00 Ужин 30 апреля 1 61.78kb.
Лекция №11. Метод штрафных функций 1 63.19kb.
Учебная программа курса. Рабочая программа курса. Лекция История... 18 4268.84kb.
Лекция №1 2 Лекция №2 8 Лекция №3. 13 Лекция №4 14 Лекция №24 Лекция... 1 316.74kb.
Лекция 2 методы биохимии 1 95.44kb.
Диаграммы потоков данных 1 106.02kb.
Аналитические методы работы в журналистике 1 92.6kb.
Социального государства 1 271.74kb.
Направления изучения представлений о справедливости 1 202.17kb.

Лекция 2 курса «Методы автоматизации тестирования» - страница №1/1

Лекция 2 курса «Методы автоматизации тестирования»

Цели


  1. Ознакомительные

    1. Ознакомить слушателей с шаблонами «оракул» и «медиатор» и их использованием при организации тестовых систем.

    2. Продемонстрировать возможность автоматического построения оракулов на основе формальных спецификаций.

    3. Ознакомить слушателей с конструкциями языка J@va, используемыми при разработке спецификаций и медиаторов, и инструментом J@T.

  2. Учебные

    1. Перечислить основные компоненты тестовой системы J@T, определить задачи, решаемые каждым из них в тестовой системе, описать основные связи между ними.

    2. Дать материал, необходимый для разработки спецификаций на J@va для простых примеров ПО (функция, простой класс — с несложным состоянием и 2-5 методами).

    3. Дать материал, необходимый для разработки при помощи J@T медиаторов на J@va для тестирования простых примеров ПО с открытым состоянием (функция, простой класс).

План


Общая архитектура теста по UniTesK.

Проблема проверки корректности результатов.

Шаблон тестирования «оракул». Разновидности оракулов.

Построение оракулов из формальных спецификаций.

Спецификации на J@va и построение оракулов на их основе.

Проблема определения полноты тестирования.

Критерии покрытия, определяемые спецификациями на J@va.

Проблема гибкости и многократного использования тестов.

Использование шаблона «адаптер» для тестирования.

Медиаторы на J@va.


Литература


[1] B. Beizer. Software Testing Techniques. 2-nd edition.

[2] Robert B. Binder. Testing Object-Oriented Systems. Models, Patterns, and Tools. Addison-Wesley Longman. 2000.

[3] Г. Маейрс. Надежность программного обеспечения. «Мир», Москва, 1980.
Glenford J. Myers. Software Reliability. Principles and Practices. John Wiley & Sons, 1976.

[4] Б. Лисков, Дж. Гатэг. Использование абстракций и спецификаций при разработке программ. «Мир», Москва, 1989.


Barbara Liskov and John Guttag. Abstraction and Specification in Program Development. The MIT Press McGraw-Hill.

[5] E. Gamma, R. Helm, R. Johnson, J. Vlissides. Design Patterns. Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994.


Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. Паттерны проектирования. 2001, Питер.

Предварительные данные


Табличка с шагами технологии

Табличка со спецификой UniTesK



Модели

Вид модели, используемый UniTesK

Представление проверяемых свойств

Формальные специфкации

Модель поведения

Ограничительные спецификации

Критерии тестового покрытия

Покрытие спецификаций

Модель тестирования

Модель черного ящика

Модель построения тестов

Тестирование на основе автоматов + Комбинаторное

Содержание


  1. Моделирование области решения

На этом шаге определяется, как именно мы будем проводить тестирование, и как будет устроено построение тестовых программ. Нужно определить способы построения элементов тестовой программы из данных, которые были определены на предыдущих шагах.

Для автоматизации важно, чтобы как можно большая часть этого процесса могла бы быть проведена автоматически.




Как строить тесты, имея формальные спецификации целевой программы и критерий покрытия?
Задачи, решаемые тестовой программой группируются в две группы.

Проверка корректности результатов работы целевой программы.

Достижение заданного уровня полноты тестирования.

Формальные спецификации можно использовать для проверки корректности результатов, а именно, соответствия поведения целевой программы требованиям.



Как получать наборы (последовательности тестовых воздействий), приводящие к нужному уровню покрытия?

Для этого используются модели построения тестов.

  1. Вероятностное тестирование.

  2. Комбинаторное тестирование.

  3. Тестирование на основе автоматов.

  4. Тестирование по алгебраическим моделям.

Первые два вида моделей применимы только для систем, поведение которых не зависит от истории.
Для первой модели это можно поправить, используя вместо обычных распределений случайные процессы. Обычно используются марковские цепи.

Такая модель требует больших знаний о шаблонах использования ПО и о затратах на возможные ошибки, а для марковских цепей количество необходимых знаний возрастает. Откуда их взять?

Последняя модель не дает обоснованного ответа на вопросы: какие затравочные последовательности использовать, а какие нет, и сколько преобразований достаточно для достижения нужного покрытия.
UniTesK использует в качестве основной третью модель, причем конечный автомат, используемый для построения теста, строится на основе выбранного критерия покрытия. Это тема лекции 3.
Вторая модель используется для генерации тестовых воздействий в одном состоянии.


  1. Предварительное проектирование

Этот шаг определяется используемой технологией архитектурой тестовой системы.

UniTesK использует следующую архитектуру.



Обходчик автоматов и итератор тестовых воздействий совместно решают задачу построения тестовой последовательности для достижений выбранного уровня покрытия. При этом обходчик представляет собой общий алгоритм для построения обхода по переходам для автоматов некоторого широкого класса, а итератор тестовых воздействий заключает в себе описание автомата, моделирующего целевую систему таким образом, что его обход гарантирует достижение нужного покрытия.

Подробнее о них будет говориться на следующей лекции.



Оракул решает задачу проверки корректности поведения целевой системы.

Медиатор отделяет оракул от целевой системы, делая возможным многократное использование одного и того же оракула.

Итератор тестовых воздействий, оракул и медиатор автоматически генерируются из компактных описаний на языке J@va, называемых, соответственно, тестовым сценарием, спецификацией и медиатором.

В результате основная работа по предварительному проектированию тестов в рамках UniTesK состоит в проектировании набора тестовых сценариев.



  1. Детальное проектирование

На этой лекции мы рассмотрим устройство оракула и медиатора на целевом языке, а также оформление на J@va спецификаций и медиаторов, из которых первые получаются автоматически.




Оракулом вообще в рамках тестирования называют любой способ определения «правильно» ли ведет себя целевая система или нет.

В литературе упоминаются следующие разновидности оракулов.



  1. Проверка результатов человеком. Для автоматизации плохо.

  2. Сравнивающие оракулы.
    Общая слабость: непонятно, откуда брать критерии сравнения. В [2] целый раздел главы 18 посвящен различным методам сравнения: по идентичности, по полям, в глубину.


    1. Сравнение получаемых результатов с заранее перечисленными в таблице.
      Плохо в связи с привязкой к конкретным воздействиям.

    2. Вычисление результатов более простым алгоритмом, при помощи надежной программы, предыдущей версии.
      На основе спецификаций: результаты получаются при помощи исполнимой спецификации или автоматически сгенерированной программы, эквивалентной последовательности операций, полученной из алгебраической спецификации.
      Плохо в некоторых случаях, где в качестве правильного может выступать много результатов: недетерминизм, приближенные вычисления и пр.

    3. Сравнение трёх и более результатов разных версий.
      Нет гарантий правильности.

  3. Оракулы, основанные на обращении целевой операции — вычисление аргументов по результатам и сравнение полученных аргументов с фактическими.
    Целевая операция должна быть однозначно обратима.

  4. Оценивающие оракулы.


Такой оракул более гибок при использовании, может оценивать правильность работы и для недетерминированных систем и приближенных вычислений.

Кроме того, в зависимости от реализации, оракулы могут встроенными в целевую систему или внешними.

Поскольку UniTesK использует ограничительные спецификации, допускающие достаточно общие предикаты в качестве критерия корректности, из них легче получать оценивающие оракулы.





На прошлой лекции отмечалось, что технология UniTesK использует в качестве спецификаций ограничительные спецификации в виде пред- и постусловий. Эти спецификации записываются на языке J@va, являющемся расширением Java.

Пример спецификации функции вычисления логарифма (без ветви).



specification package;

public class LogSpecification

{

specification public double log(double x)



reads x

{

pre { return x > 0; }



post

{

branch “Single branch”;



return Math.exp(log) == x;

}

}



}

Спецификационные методы — помечаются модификатором specification.

Могут иметь ограничения доступа, описывающие способ работы данной операции с данными, доступ на которые определяется. Виды ограничений доступа


  • reads
    Доступ только на чтение, в оракуле проверяется, что значение не изменилось

  • writes
    Доступ только на изменение. Поведение операции не должно зависеть от таких данных. В оракуле ничего не проверяется, но можно сделать несколько тестов с разными исходными значениями указанных данных и проверить, что операция ведет себя одинаково.

  • updates
    Такие данные могут изменяться операцией, и её поведение может зависеть от них. Ничего не проверяется.

Доступ может указываться на значение (как в примере) или на все поля некоторого объекта — тогда пишется, например, reads object.?

Выбрасываемые исключения укзаываются также, как в Java.



Предусловие — блок, помеченный pre и содержащий тело, возвращающее значение типа boolean. Поведение операции проверяется только если предусловие выполнено. Если операция вызывается при невыполненном предусловии, ее поведение не определено — она может как-то отработать, вызвать ошибку в системе, стереть все данные, не вернуть управление и пр.
Предусловие может быть опущено, что означает, что оно всегда выполняется, т.е., эквивалентно pre { return true; }

Постусловие— блок, помеченный post и содержащий тело, возвращающее значение типа boolean.

К результату операции в постусловии можно обращаться, используя имя спецификационного метода. К созданному операцией исключению можно обрщаться, используя идентификатор thrown, имеющий тип Throwable.

Значения выражений до вызова целевой операции можно получить с помощью оператора пре-значения @.

В классе могут определяться инварианты — особые методы, помеченные модификатором invariant , без указания типа возвращаемого значения и без параметров, тело их должно возвращать значение типа boolean. Инварианты представляют собой общие части всех пред- и постусловий для всех методов, работающих с объектами данного класса.

Пример. Инвариант представления комплексных чисел в виде модуля и аргумента.

specification package;

public class ComplexNumberSpecification

{

double r;



double phi;
invariant I()

{

return 0 < r && -Math.PI < phi && phi <= Math.PI

&& 0 == r && 0 == phi;

}

}






На прошлой лекции отмечалось, что технология UniTesK использует в качестве критериев покрытий критерии покрытия спецификаций. Возможность гибкого задания требуемого уровня покрытия в таком случае предполагает возможность детализации структуры спецификаций. Нам не достаточно становится один раз вызвать заданную операцию.

Для того, чтобы стало возможно автоматически провести анализ структуры спецификаций, в них добавляются дополнительные операторы, указывающие различные ветви функциональности — области, где описываемая операция ведет себя существенно по-разному, т.е., ограничения на её поведение описываются разными выражениями.

Пример.
specification package;

public class LogSpecification

{

specification public double log(double x)



reads x

throws IllegalArgumentException

{

post

{

if(x > 0)

{

branch “Normal case”;



return thrown == null && Math.exp(log) == x;

}

else



{

branch “Exceptional case”;

return thrown != null

&& thrown instanceof IllegalArgumentException;

}

}

}



}

Операторы branch должны определять сечение графа потока управления постусловия, т.е., на каждом пути от входа в постуслвоия до любого ихз выходов должен встретиться ровно один оператор branch.

Помимо ветви функциональности оператор branch определяет место фактичекого вызова целевой операции. Таким образом, все данные до branch рассматриваются как пре-значения. Результатом операции, созданным ей исключением и оператором пре-значения @ можно пользоваться только после оператора branch.

Дополнительно можно определять более детальные разбиения области определения при помощи операторов mark. Элемент такого разбиения соответствует возможной последовательности операторов mark, оканчивающейся на branch.

Автоматически на основе выделенных ветвей функциональности строятся еще два критерия: покрытие предикатов, элементы которого соответствуют всем возможным путям, определяемым ветвлениями до операторов branch, и покрытие дизъюнктов, элементы которого соответствуют всем возможным комбинациям значений элементарных логических формул, встречающихся в ветвлениях до операторов branch.





Медиатором мы будем называть любой способ организации связи и передачи сообщений между оракулом и целевой системой. Простейшим медиатором является тривиальный — оракул сам работает непосредственно с целевой системой.

Это, однако, не удобно, если мы хотим обеспечить возможность использовать одни и те же спецификации и тесты многократно.

При этом, вследствие внесения изменений и дополнений как в целевую систему, так и в спецификации между ними может возникнуть несоответствие интерфейсов или даже несоответствие уровней абстракции (типов данных состояния, аргументов и результатов).

В таком случае требуется какой-то способ преобразования обращений оракула к целевой системе и её ответов на эти обращения.

В [5] для этого подходят шаблоны «адаптер», «мост», «прокси».
Из них наиболее удобным с точки зрения UniTesK выглядит первый — он даёт способ реализовать интерфейс, декларированный в спецификациях, с которым может работать оракул, при помощи реализационных компонентов.

Поскольку медиатор обычно содержит много вспомогательного очень регулярно устроенного кода, его проще генерировать из некоторого представления на J@va.






Медиаторные классы помечаются модификатором mediator.

Пример медиатора.

Для комплексных чисел, которые в спецификации представляются модулем и аргументом, а в реализации — действительной и мнимой частями.

specification package;

mediator public class ComplexMediator

extends ComplexNumberSpecification // наследует спецификации

{

implementation Complex target; // ссылка на целевой объект


public static ComplexNumberSpecification

multiply(ComplexNumberSpecification x,

ComplexNumberSpecification y)

// переопределяет статический спецификационный метод

{

// преобразование аргументов в реализационное представление



Complex arg1 = ((ComplexMediator)x).target;

Complex arg2 = ((ComplexMediator)y).target;


// вызов целевой операции

Complex res = Complex.multiply(arg1, arg2);


// преобразование результата в модельное представление

return ComplexMediator.create(res);

}
public void conjugate()

// переопределяет нестатический метод, изменяющий состояние

{

// вызов целевой операции



target.conjugate();

}

}



Медиатор наследует спецификационному классу, операции которого он должен определить через реализацию.

Объекты целевой системы, реализующие эти операции, называются реализационными ссылками. Они оформляются в виде полей медиаторного класса, помеченных implementation.

Синхронизация состояний.

Тестирование с открытым и закрытым состоянием.

Оба вида тестирования используются в рамках тестирования «черным ящиком».

При тестировании с открытым состоянием мы имеем надежный способ узнать информацию о текущем состоянии реализации (доступные поля или надежные методы чтения), достаточную для построения модельного состояния на её (информации) основе. Новое состояние модельного объекта строится при этом медиатором только на основе полученной от реализации информации. Процедура построения очередного модельного состояния записывается в методе mapStateUp() медиаторного класса. Этот метод автоматически вызывается после каждого обращения к целевой операции.

Пример mapStateUp() для предыдущего примера.

public void mapStateUp()

{

r = Math.sqrt(target.x*target.x + target.y*target.y);



phi = Math.atan2(target.y, target.x);

}

При тестировании со скрытым состоянием новое модельное состояние вычисляется на основе старого и данных о вызванной операции — её аргументах и результате. Оно используется, если нет надежного доступа к необходимым данным о состоянии реализации. При таком тестировании модельное состояние не напрямую соответствует реализационному, а есть некоторая гипотеза о том, в каком состоянии сейчас может оказаться система, учитывая историю работы с ней. Синхронизация модельного состояния с реализационным при таком способе тестирования описывается в каждой перегруженной медиатором операции отдельно.



В предыдущем примере при тестировании со скрытым состоянием второй метод надо переписать так.

public void conjugate()

// переопределяет нестатический метод, изменяющий состояние

{

// вызов целевой операции



target.conjugate();

// обновление модельного состояния

if(phi != Math.PI) phi = -phi;

}

Тестирование с открытым состоянием более просто. Для проверки корректности работы целевой системы (в предположении, что в состояниях, соответствующих одному модельному она ведет себя одинаково) достаточно в этом случае вызвать каждую операцию в каждом из модельных состояний. Обнаруженная при таком тестировании ошибка в работе реализации связана с последней вызванной операцией.



При тестировании со скрытым состоянием недостаточно вызвать каждую операцию в каждом модельном состоянии, поскольку нет уверенности в том, что система действительно находилась в состояниях, соответствующих пройденным модельным. Обнаруженное несоответствие модели ошибка может быть проявлением ошибки, произошедшей гораздо раньше, и для её локализации в общем случае требуется анализ всей истории теста.

Общая схема работы медиатора.


Шаблон построения медиаторов в J@T.





Мы легко забываем свои ошибки, когда они известны лишь нам одним. Франсуа Ларошфуко
ещё >>