Лекции. Тестирование ПО (all in one) (1186159), страница 33
Текст из файла (страница 33)
Если это не так, то нужно выделить такиеатомарные действия и указывать их в модели в качестве возможных воздействийна систему и ее реакций. При этом может оказаться, что возвращение операциейуправления нужно описать как отдельное действие, поскольку ее результат можетзависеть от того, какие другие операции были вызваны во время ее работы.Разработка и выполнение тестовРазработка и выполнение тестов объединены в одну деятельность, поскольку собственноразработка тестов обычно происходит вперемешку с их прогонами и отладкой.
При отладкетестов устраняются все обнаруживаемые ошибки в модели поведения и самих тестах,остаются только те, источник которых — некорректное поведение тестируемой системы.Деятельность по разработке тестов может быть разделена на следующие действия.1. Выбор общей схемы теста для данного компонента (группы компонентов).Сначала на основе того, что известно о поведении компонентов и требованиях кполноте их тестирования нужно определить виды тестов, которые необходимо дляних разработать.
Это могут оказаться простейшие тесты, которые проверяюттолько, что вызываемая один раз операция возвращает результат, как-то похожийна правильный. Это могут быть тесты, проверяющие работу каждой операции внескольких ситуациях, соответствующих различным вариантам ее использованияили разным ветвям функциональности. Это могут быть более сложные тесты,проверяющие корректность работы группы операций с общим состоянием спомощью обхода автомата, моделирующего поведение этой группы операций.Еще более сложные тесты могут проверять поведение данной группы операций взависимости от других операций, которые могут изменять общее состояниепервых, или проверять корректность параллельной работы всех пар или троекопераций из заданной группы.С точки зрения построения схемы теста также важно, какие операции (может бытьодна) в нем будут участвовать, какого рода ситуации в этом тесте будусоздаваться, будет ли использоваться внутреннее состояние тестируемогокомпонента, будут ли нужны нетривиальные тестовые данные, будет ли нуженпараллелизм.
Схема выбирается в соответствии с некоторой подходящейкомбинацией перечисленных выше техник.2. Определение дополнительных проверок (если нужно).Иногда не все проверки корректности поведения стоит оформлять вспецификациях отдельных операций, поскольку для их выполнения необходимознать полную историю обращений к системе или значительную ее часть. В этомслучае то, что можно проверить в рамках вызова одной операции (на основетекущего состояния и аргументов вызова), проверяется в ее постусловии, а тепроверки, для которых необходимо знать больше об истории обращений,записываются в тестовом сценарии.Например, для тестирования генератора случайных чисел можно написатьспецификацию, в которой проверять только принадлежность результата заданномуинтервалу.
А в рамках сценария можно собирать все получаемые результаты ипроверять общие ограничения на их распределение, используя, например,критерия Колмогорова.3. Разработка генераторов тестовых данных (если нужно).Если необходимо использовать нетривиальные тестовые данные, для ихпостроения разрабатывается набор генераторов с помощью подходящейкомбинации техник, описанных в предыдущем разделе.4. Определение состояний и действий, построение автомата теста (если нужно).Для тестирования компонентов, поведение которых зависит от внутреннегосостояния, тесты обычно разрабатываются с использованием автоматной моделитакого компонента по одной из техник, описанных выше.5.
Разработка адаптеров (если нужно).Если интерфейс тестируемой системы несколько отличается от того интерфейса еемодели поведения, для преобразования вызовов между этими двумя интерфейсамииспользуются тестовые адаптеры.Тестовые адаптеры бывают разных видов, в зависимости от двух факторов: вкакую сторону они выполняют преобразование (из модели в реализацию илиобратно), и какого рода связи с моделью и с реализацией (тестируемой системой)они используют.Модельно-реализационные адаптеры выполняют преобразование обращений измодельного интерфейса в реализационный, а результаты операций илиасинхронного возникающие события преобразую обратно — из реализационноговида в модельный.Реализационно-модельные адаптеры производят все преобразования только изреализационного вида в модельный.Модельно-реализационный адаптер может оформляться в виде класса,наследующего модельный класс и использующего классы тестируемой системы.Адаптеры, переводящие события из реализации в модель, наоборот, удобнееделать реализующими какие-то интерфейсы тестируемой системы ииспользующими модельные классы для сохранения информации о передаваемыхими событиях.Например, модельно-реализационный адаптер, реализующий описанный впредыдущей лекции класс спецификации списка через java.util.Vector можетвыглядеть примерно так.public mediator class VectorAdapter<E>implements ListSpecification<E>{implementation Vector target;public mediator void add(int i, E o)throws IndexOutOfBoundsException{implementation { target.insertElementAt(o, i); }update{E[] newItems = new E[items.length + 1];System.arraycopy(items, 0, newItems, 0, i);newItems[i] = o;System.arraycopy(items, i, newItems, i+1, items.length-i+1);items = newItems;}}...}В приведенном примере в блоке update выполняется экстраполяция новогосостояния модели в текущей ситуации.
Если же, например, можно использоватьрезультаты методов size и getElementAt как достоверные сведения о текущемсостоянии вектора, можно вместо блоков update в каждом из методов-адаптеровнаписать один общий блок update для всего класса.public mediator class VectorAdapter<E>implements ListSpecification<E>{...update{if(target == null) items = new E[];else{items = new E[target.size()];for(int i = 0; i < target.size(); i++)items[i] = target.getElementAt(i);}}...}6.
Прогоны и отладка тестов.Ну, и наконец, в рамках этого этапа необходимо оформить тесты и отладить их.Разберем построение автоматного теста для списка, спецификации которого описаны впредыдущей лекции. Напомним, что для его тестирования выбран критерий полноты,требующий проверить работу списка в нормальных и исключительных ситуациях дляметодов add и remove, для метода indexOf — при наличии аргумента в списке и при егоотсутствии. Кроме того, для всех методов нужно проверить их работу для пустого списка, адля методов remove и indexOf — для списка, содержащего только один элемент.При построении автоматного теста, нацеленного на достижения заданного критерияполноты тестирования, используется редукция модели по критерию полноты.
Приприменении этой техники по набору контрактов и критерию полноты строится автоматнаямодель, проход по всем переходам которой гарантирует достижение заданного критерия.Такая редукция выполняется следующим образом.1. Выделение целей тестирования.На первом шаге для каждой операции перечисляются выделяемые критериемполноты тестирования ситуации — это и есть цели тестирвоания.В нашем случае перечень этих ситуаций такой.• Метод add.o пустой список и корректный индекс;o пустой список и некорректный индекс;o непустой список и корректный индекс;o непустой список и некорректный индекс.•Метод remove.o пустой список;o список с одним элементом и корректный индекс;o список с одним элементом и некорректный индекс;o список с двумя или более элементами и корректный индекс;o список с двумя или более элементами и некорректный индекс.• Метод indexOfo пустой список;o список с одним элементом и аргумент в списке;o список с одним элементом и аргумента нет в списке;o список с двумя или более элементами и аргумент в списке;o список с двумя или более элементами и аргумента нет в списке.Эти ситуации представляются как ограничения, вырезающие из областиопределения операции подобласти в пространстве возможных состояний системыи аргументов операции.2.
Получение обобщенных состояний и действий.Далее все области, соответствующие различным ситуациям, проецируются напространство состояний. Рассматриваются все возможные пересеченияподмножеств этих проекций. Полученные в итоге множества состояний длякаждой проекции должны либо входить в нее, либо не пересекаться с ней. Этимножества образуют разбиение всех состояний на классы эквивалентности.ПараметрыОбласть определенияОбласти, соответствующиеразличным ситуациямСостоянияРисунок 1. Построение обобщенных состояний и действий.Полученные так множества состояний — обобщенные состояния — являютсякандидатами на роль состояний автомата, моделирующего систему.
Действия вэтом автомате соответствуют всем возможным ситуациям. Проход по всем егопереходам будет означать, что все исходные ситуации проверены.В нашем примере такими пересечениями проекций ситуаций являютсяследующие обобщенные состояния.• Пустой список.• Список с одним элементом (произвольным).• Список с двумя или более элементами.3. Детерминизация полученного автомата.Полученный автомат может оказаться непригодным для контролируемоготестирования из-за высокой степени недетерминизма. Если он детерминирован —каждое действие в каждом обобщенном состоянии приводит в однозначноопределяемое обобщенное состояние, то все хорошо.
Если же это не так, чточтобы сделать его детерминированным, нужно расщепить те состояния, где естьнедетерминированные действия. Каждый раз, когда у действия в некоторомобобщенном состоянии может быть несколько возможных исходов (конечныхсостояний), мы разделяем это состояние на такие части, чтобы в каждой из этихчастей исход действия определялся однозначно.Выполнение этого расщепления не всегда приводит в итоге к детерминированномуавтомату. В таком случае можно попробовать разделить операции на несколькогрупп, оставив в каждой из этих групп по одной из операций, порождающихнедетерминированные действия. При таком делении часто можно построитьнесколько различных детерминированных автоматов (каждый соответствуеттолько части операций, одна операция может использоваться в несколькихавтоматах), обход каждого из которых дает желаемое покрытие всех ситуаций.В нашем примере источник недетерминизма один — при выполнении remove всписке с двумя или более элементами мы можем остаться в том же обобщенномсостоянии (список будет иметь два или более элемента), а можем получить списокс одним элементом.Чтобы удалить недетерминизм, нужно выделить в отдельное обобщенноесостояние списки с двумя элементами.
В оставшемся множестве — списки с тремяили более элементами — все равно останется тот же недетерминизм. Чтобы егоудалить совсем, придется различать списки с различным числом элементов.Заметьте, что в полученном автомате никак не учитывается. Какие именноэлементы находятся в списке — важно только их число.Действия в этом автомате соответствуют исходным ситуациям (аналогичныедействия в различных состояниях можно обозначать одним способом).• Добавить элемент с корректным индексом.• Добавить элемент с некорректным индексом.• Удалить элемент с корректным индексом.• Удалить элемент с некорректным индексом.• Найти индекс первого вхождения элемента, отсутствующего в списке.• Найти индекс первого вхождения элемента, присутствующего в списке.4. Ограничение полученного автомата.После предыдущего шага автомат может оказаться бесконечным.
Тестированиеявляется конечной процедурой, и для построения тестов нам достаточно какой-токонечной части этого автомата. Поскольку исходных целей тестирования конечноечисло, они достигаются при проходе по всем переходам в некотором конечномподавтомате. Чтобы выделить его, достаточно в некоторых состояния запретитьдействия, «уводящие дальше от начального состояния».Обычно такие пороговые состояния можно определить небольшим наборомпараметров. Эти параметры можно сделать параметрами теста, чтобы по одному итому же описания можно было строить тесты различной сложности.В примере тестирования списка «уводящей от начального состояния» операциейявляется добавление элементов. Достаточно запретить его при достижениинекоторого максимально возможного в тесте количества элементов N.