Тестирование с обобщенным состоянием Обобщение состояния - umotnas.ru o_O
Главная
Поиск по ключевым словам:
страница 1
Похожие работы
Название работы Кол-во страниц Размер
Механика алюшин ю. А 1 223.25kb.
Психологическое тестирование при подборе персонала 1 96.59kb.
Конспект урока Обобщение и систематизация сведений по теме «Деепричастие»... 1 38.8kb.
[Физика конденсированного состояния] 1 47.18kb.
Научно-практическая конференция «Обучение, тестирование и оценка... 1 37.4kb.
К рабочей программе дисциплины «Физика конденсированного состояния»... 1 21.25kb.
Теория пластичности 1 30.73kb.
Билет №1 Термодинамические системы. Релаксация и термодинамическое... 1 87.1kb.
Оценка состояния соснового бора 1 80.88kb.
Разработка сценария диалога 1 62.21kb.
Обобщение по уголовным делам, рассмотренным в 2012 году, частно-публичного... 1 117.8kb.
Определение. Конечный автомат a = 1 58.42kb.
Викторина для любознательных: «Занимательная биология» 1 9.92kb.

Тестирование с обобщенным состоянием Обобщение состояния - страница №1/1


Тестирование с обобщенным состоянием

Обобщение состояния


На предыдущем занятии был рассмотрен подход к тестированию группы функций, поведение которых зависит от истории их вызовов. Зависимость поведения от этой истории описывается при помощи состояния системы, которое изменяется в результате вызовов функций группы, и от которого зависят результаты этих вызовов.
Алгоритм, реализованный в единственном на настоящий момент обходчике dfsm, обеспечивает тестирование всех допустимых ветвей функциональности каждой функции группы во всех достижимых состояниях системы. На практике количество различных состояний, определяемых спецификациями реальных систем, настолько велико, что тестирование в каждом из них является невыполнимой за разумное время задачей.
Кроме того, для корректной работы обходчика требуется, чтобы при всех вызовах любой целевой функции группы с одними и теми же параметрами в одном и том же состоянии система переходила в одно и то же состояние (требование детерминированности). Но группа функций с состоянием, определенным в спецификациях, не всегда обладает этим свойством.
Эти проблемы решаются при помощи введения отношения эквивалентности на множестве состояний системы. Каждый класс эквивалентных состояний, порождаемый данным отношением эквивалентности, называется обобщенным состоянием.
Например, при разработке тестового сценария для тестирования стека можно считать эквивалентными состояния, в которых в стеке содержится одинаковое количество элементов. В этом случае обобщенным состоянием будет размер стека.
Использование обобщенных состояний вместо обычных состояний системы позволяет обходчику сократить количество необходимых вызовов тестируемых функций до разумных значений, а также избавиться от недетерминированности. С другой стороны, за это приходится расплачиваться некоторым снижением подробности тестирования: вместо тестирования каждой функции в каждом достижимом состоянии системы, обходчик будет тестировать каждую функцию в каждом достижимом обобщенном состоянии.
Под тестированием функции в обобщенном состоянии системы понимается множество вызовов этой функции в тот момент, когда система находится в некотором состоянии, принадлежащем данному обобщенному состоянию.
Если суммировать все требования, налагаемые обходчиком на группу сценарных функций, и отношение эквивалентности на множестве состояний системы, то получится следующее:
[ Детерминированность ]

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


[ Связность ]

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


Обобщение состояния ведет к некоторому снижению подробности тестирования. Однако при выполнении некоторых предположений, качество тестирования при этом не снижается.
Предположим, что верна следующая гипотеза.
Если функция при вызове в данном состоянии с данными входными параметрами работает правильно, то она будет работать правильно и при всех ее вызовах во всех состояниях, которые принадлежат тому же множеству эквивалентных состояний, что и данное состояние, с любыми входными параметрами, которые относятся к той же ветви функциональности, что и данные параметры.
Тогда, если обходчик достигнет своей цели (то есть вызовет каждую сценарную функцию в каждом достижимом обобщенном состоянии в каждой допустимой ветви функциональности) и не обнаружит никаких ошибок, то из этого будет следовать, что и при тестировании без обобщения ошибок обнаружено не будет.
Заметим, что огромную роль в жизнеспособности данной гипотезы играет разбиение пространства входных параметров функции на ветви функциональности, осуществляемое в блоке coverage. И чем ближе разбиение на ветви функциональности к разбиению области определения функции, реализуемой целевой системой, на подобласти, для каждой из которых выполняется следующее утверждение: «Для подобласти входных данных реализация однородна в смысле наличия ошибок: либо правильна, либо неправильна, т.е. ошибка, если она есть, будет выявляться на любом представителе из подобласти», тем больше оснований полагаться на данную гипотезу.
Таким образом, при данных неформальных условиях обобщение состояния позволяет тестировать целевую систему за разумное время и без потери качества.

Пример обобщения состояния системы


Рассмотрим пример системы, тестировать, которую средствами CTesK без обобщения состояния не представляется возможным.

В системе определены две функции



  • pid_t create_process()

  • void kill_process(pid_t pid)

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

Функция kill_process() уничтожает процесс с идентификатором pid. Если идентификатор pid не был ранее возвращен функцией create_process() или уже был уничтожен ранее, то поведение системы не определено.

Состояние спецификации задается множеством идентификаторов существующих процессов.

Обобщение состояния требуется по обоим причинам, которые мы рассматривали ранее:



  1. Число состояний спецификации чрезмерно велико.

  2. Поведение функции create_process() недетерминировано.

Рассмотрим последнее утверждение. В описании функции не указывается, какой идентификатор должен возвращаться. В принципе, в одном и том же состоянии спецификации (т. е. при одинаковом множестве идентификаторов существующих процессов) функция может вернуть различные значения (например, pid1 и pid2), и система перейдет в различные состояния (отличающиеся только этими идентификаторами).

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

Тогда мы получим детерминированную модель, пригодную для тестирования. Покажем, что данная модель детерминирована. Рассмотрим произвольное состояние системы. Пусть оно является представителем обобщенного состояния N.



Функция create_process() возвращает произвольный идентификатор процесса, отличающийся от идентификаторов существующих. Значит, число существующих процессов увеличивается на единицу. То есть независимо от того, какой идентификатор возвращает функция create_process(), система переходит в состояние, принадлежащее обобщенному состоянию N+1. Требование детерминированности выполняется. Для того, чтобы ограничить количество состояний, следует ввести максимальное число существующих процессов, и при достижении этого числа функцию create_process не вызывать.
Функция kill_process() должна получать идентификатор существующего на данный момент процесса. В модельном множестве содержатся как раз такие идентификаторы, в качестве параметра функции следует передавать какой-нибудь элемент этого множества. Таким образом, эта функция всегда уничтожает процесс, идентификатор которого она получает как параметр. Значит число существующих процессов уменьшается на единицу. То есть система переходит в состояние, принадлежащее обобщенному состоянию N-1. В состоянии, в котором нет процессов, эта функция вызываться не должна.

Сценарий с обобщением состояния


Состояние обобщается в тестовом сценарии. Обобщение состояния задается функцией, именем которой инициализируется поле getState сценария тестирования. В отличие от рассмотренного ранее случая тестирования без обобщения состояния эта функция возвращает не копию состояния спецификации, а значение, идентифицирующее класс эквивалентности, к которому относится текущее состояние спецификации.
Функция, строящая обобщенное состояние по текущему состоянию спецификации, задает отношение эквивалентности на множестве состояний системы: два состояния являются эквивалентными, если данная функция возвращает в них равные значения спецификационного типа, представляющего обобщенное состояние. Под равенством в данном случае понимается сравнение этих значений с помощью библиотечной функции compare().
При описании обобщения состояния, всегда необходимо учитывать требования, налагаемые обходчиком: детерминированность и связность.
Если поле getState опущено в описании сценария, то считается, что все состояния системы являются эквивалентными между собой. Заметим, что при этом соблюдаются все требования налагаемые обходчиком, и поэтому такое обобщение всегда является корректным.
Остальная часть описания сценария тестирования, за исключением разработанной по особым правилам функции построения состояния, остается такой же, как и в случае тестирования группы функций без обобщения состояния.
Чтобы обеспечить детерминированность обобщенного состояния для некоторых систем, при описании итерации приходится использовать достаточно сложную схему. Рассмотрим, например, систему, обеспечивающую работу с множеством целых чисел, находящихся в некотором диапазоне.
IntSet *set_model;
specification bool add_set_spec (int i) updates set_model;

specification bool remove_set_spec (int i) updates set_model;

specification bool in_set_spec (int i) reads set_model;
В качестве обобщения состояния для написания сценария выберем текущий размер множества.
Integer *set_get_state () {

return create (&type_Integer, size_IntSet (set_model));

}
При написании сценарной функции для спецификации add_set_spec() следует учитывать, что в одном и том же обобщенном состоянии при одном и том же значении параметра i система может остаться в прежнем состоянии (если множество содержит i) или перейти в другое состояние (если i в множестве отсутствует). Таким образом, воспользоваться оператором iterate и передавать значение итерационной переменной спецификационной функции не получится.
Для упрощения написания сценарных функций можно воспользоваться итерацией по элементам покрытия — перебирать не значения параметров спецификационной функции, а ее ветви функциональности. Далее для данной ветви функциональности следует найти такой набор параметров, который ей соответствует, и вызвать с ним спецификационную функцию.
При этом требуется, чтобы поведение спецификационной функции было детерминировано для данной ветви функциональности и для любого состояния, соответствующего данному обобщенному состоянию, т.е. из любого состояния, соответствующего данному обобщенному состоянию, при любом наборе параметров, соответствующем данной ветви функциональности, вызов функции переводил бы систему в состояния, соответствующие одному и тому же обобщенному состоянию.
Для вышеприведенного примера сценарная функция для add_set_spec() с использованием итерации по элементам покрытия будет выглядеть следующим образом:
scenario bool add_set_scen () {

iterate (int b = 0; b < get_coverage_size_add_set_spec (); b++) {

int i;

for (i = MIN_VALUE; i <= MAX_VALUE; i++)

if (b == coverage add_set_spec (i)) {

add_set_spec (i);

break;

}

return true;



}