Тестирование софта - статьи

           

Как на практике?


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



Как построили работу?


Основываясь на опыте работы в паре в бытность разработчиком, и на подсмотренные у ХР-команды «манёвры», мы менялись раз в 15 минут. Попеременно «штурмуя» и «пилотируя» устаёшь меньше — это могу сказать с уверенностью. Внимание не рассеивается. Постоянное общение не даёт «залипать» в трудных моментах. Штурман идёт по чек-листу и периодически направляет пилота — делаем раз, два, три, потом смотрим: здесь, здесь, здесь… Потом меняемся.



На чём экономим?


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



Парное тестирование — возьмём от ХР лучшее


, автор проекта "Тестер",

Совершенно верно, парное тестирование, то есть работа двух тестировщиков в паре над одной задачей и буквально за одной машиной.

Работа в паре присуща экстремальному программированию, собственно видя как работают в паре наши ХР-шники (я говорю о ХР-team компании в которой я работаю на данный момент) я и решил опробовать этот подход со своими коллегами по отделу. Наблюдая практическое применение ХР при решении разноплановых задач и ту лёгкость в управлении ресурсами которую даёт ХР-команде применения основ методологии ХР, я решил взять некоторые аспекты для работы команды тестирования. Возьмём от ХР лучшее.

Первые результаты.


Обед у нас ровно посредине рабочего дня: работаем с 9-00 до 13-00, потом час обеда и ещё с 14-00 до 18-00 (восем часов + час обеда). К 12-00 мы полностью прошли по первому тестовому окружению. При этом не особо уставая, делая обычные перерывы на кофе, кроме того, я периодически прерывался на менеджерские задачи (катание на кресле к другим тестерам). Уточню, что до 12-00 мы успели выполнить и «вольную программу» — то есть в процессе работы возникали идеи, которые отклоняли курс от чек-листа, но мы реализовывали и их, не откладывая на потом. Обычно мы при прохождении по чек-листу, стараемся записывать идеи на «вольную программу» на листик, чтобы не сбиваться с ритма. При работе в паре, проблемы с отклонениями от ритма нет — мы ведём друг друга и спокойно возвращаемся к чек-листу, потому что штурман занят именно этим — направлением работы по тестированию и отслеживаением, в каком месте мы остановились. К обеду мы не только выполнили обычный план разделённый надвое, но и намного его опередили — процентов на 25 (3 часа вместо ориентироваочных 4-ёх). Прикнув по времени, что есть ещё полный рабочий час, мы приянлись за второе тестовое окружение. После перерыва на обед, мы смогли выделить время на актуализацию чек-листа, выполнению нескольких утомительных тасков (проверке локализации — привет японии!) и вернуться к тестированию. До вечера мы спокойно выполнили обучную норму двух тестировщиков и успели закрыть несколько сопутствующих тасков (к примеру, у штурмана на бекграунде ставилось тестовое окружение — работа не требующая пристального внимания, но нежелательная во время непосредственного тестирования).



Поставим эксперимент.




Сдвигаются два монитора — на одном открываются рабочие документы: чек-лист и release notes по последней версии продукта и наш клиент багтрекера, на второй машине запускается vmWare с тестовым окружением. Суть эксперимента — на полноценный проход по чек-листу нашего приложения под тестом (эксперимент ставился на среднем по сложности проекте) одному тестировщику требуется полный рабочий день, кроме того остаётся полчаса на свободный поиск (если к концу рабочего дня остаётся время и желание погонять приложение в вольном режиме). Посмотрим какое время потратят два тестера на эту задачу.



Психологический эффект.


Работать в паре легче. Нет впечатления (особенно у начинающих тестеров), что ты что-то пропустишь. Постоянно общаясь работающие в паре продолжают делиться информацией по проекту и опытом («у нас как-то был прикол, если японская локаль по умолчанию не установлена, то инсталлятор не «отстреливал» какой язык предлагать по умолчанию» — знакомые фразы?).



Зачем нам парное тестирование?


Первый раз я усадил двух тестеров за одну машину, когда нужно было вводить в курс дел по одному из наших проектов нового игрока нашей test-team. К слову сказать, проект вёлся нами уже несколько месяцев, функции команды тестирования по отношению к данному продукту заключались в финальном тестировании перед очередным релизом. Проект очень небольшой, документации по нему нет. Проводили то, что мы называем «профессиональным» тестированием, то есть тестированием, в котором тестировщик выполняет все функции эксперта по данной системе и владеет полным набором информации по проекту. Проект растёт, функции реализуются, назрела необходимоть формализации процесса тестирования, пусть даже и в столь небольшом проекте. Будем писать чек-листы. Новый игрок усаживается рядом с одним из опытных тестировщиков, ему же в руки вручается недружелюбный МАК (будем и с Мак ОС знакомиться и со специфичным Маковским приложением). Начинается пояснение: что за продукт, зачем, как он работает, то есть по-сути устно излагается product vision. Почему бы не положить это на "бумагу"? Открывается Excel на соседней машинке. Более опытный "штурмует" — то есть выполняет функции штурмана, поясняет и сам же записывает, пока обучаемый вникает в незнакомые кнопочки и покоряет однокнопочную мышь. Совмещая функции ознакомления и документирования начал создавать чек-лист по нашему продукту. Получается, что новый игрок не зная всех функций системы задаёт много вопросов, которые просто и понятно ложатся в основу чек-листа, а штурман обладая всеми знаниями по системе со своей стороны дополняет чек-лист ожидаемым поведением системы. Составление чек-листа, как один из аспектов тестирвоания приложения в паре даётся гораздо легче. Штурман — тот кто видит чек-лист и приложение на более высоком уровне, управляет уровнем детализации чек-листа и следит за покрытием всех тестовых сценариев, а непосредственно пилот — тестер в руках которого тестовое окружение и приложение под тестом, углубляется в тестирование как таковое, не овлекаясь на писателький труд. В данном случае парная работа была просто необходима — нужен момент передачи знаний по проекту, а кроме того, удалось сосредоточить нового игрока исключительно на проекте в новой незнакомой ему ОС.



Аннотация


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

Как эффективность обходчика влияет на тестирование


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

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

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

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

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

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

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

Рисунок 1.Граф состояний и переходов для «цепного» примера.

В этом случае возможен обход вида (перечисляются состояния в порядке их посещения) 0, 1, 0, 1, 2, 1, 0, …, 0, 1, 2, …, (n-2), (n-1), (n-2), …, 1, 0.

Также возможен обход вида 0, 1, 2, …, (n-2), (n-1), (n-2), …, 1, 0.

В обоих случаях проходятся все дуги во всех состояниях графа, однако в первом случае количество тестовых воздействий, проделанных при обходе, равно 2n(n+1)/2 = n(n+1), тогда как во втором оно составляет только 2n.

Из приведенного примера вытекает следующая рекомендация по работе обходчика: в случае наличия непройденных дуг из текущего состояния графа, обходчику рекомендуется первой вызывать операцию, соответствующую одной из этих непройденных дуг.
То есть, не рекомендуется переходить к вызову сценарной функции B, пока не исчерпаны возможные вызовы сценарной функции A. При этом порядок задания сценарных функций, определяющий последовательность их вызова обходчиком, должен тщательно обдумываться разработчиком тестов для определения максимально эффективного обхода. Примеры с потоками. Приведенные ниже примеры выбраны из-за высокой степени связности графов, а также относительно малого количества состояний и дуг, что позволяет понять существо проблемы, не рассматривая сложные случаи. О том, что такое поток (thread) и обработчик завершения потока (cleanup handler) можно прочесть в [] и [] соответственно. Простой пример с потоками. Граф состояний и переходов простой модели системы управления потоками, описываемой в стандарте POSIX [], изображен на Рисунке 2. В этой модели разрешается иметь не более одного потока одновременно.

Рисунок 2. Граф состояний и переходов для простого примера работы с потоками. Здесь первая цифра в состоянии обозначает количество активных потоков в системе, а вторая - количество зарегистрированных обработчиков завершения потоков. В POSIX есть операции создания нового потока (обозначим ее как C от create), помещения функции в стек обработчиков завершения данного потока (U, от push) и выталкивания ее из этого стека (O, pop), а также операция уничтожения данного потока (K, kill). В нашей простой модели потоку разрешается иметь не более двух обработчиков завершения. В рассматриваемом случае, даже если обходчик следует рекомендации по использованию сценарных функций, существует, по крайней мере, два возможных маршрута обхода с разной эффективностью. Первый вариант (13 переходов): [0, 0], [1, 0], [1, 1], [1, 2], [1, 1], [1, 0], [0, 0], [1, 0], [1, 1], [0, 0], [1, 0], [1, 1], [2, 1], [0, 0]. Он соответствует последовательности использования сценарных функций CUOK. Обходчик пытается в каждом состоянии вызывать функции в указанном порядке. Второй вариант (15 переходов): [0, 0], [1, 0], [0, 0], [1, 0], [1, 1], [0, 0], [1, 0], [1, 1], [1, 0], [1, 1], [1, 2], [0, 0], [1, 0], [1, 1], [1, 2], [1, 1].


Он соответствует последовательности сценарных функций CKUO. Сложный пример с потоками. Рассмотрим более сложную модель той же системы, допуская уже два активных потока.
Рисунок 3. Граф состояний и переходов более сложной модели потоков. В данном случае первая цифра в состоянии обозначает количество активных потоков. Далее идут несколько цифр, отражающих количество обработчиков завершения для соответствующих потоков. В системе имеются те же операции, что и раньше, но на этот раз разрешим потоку иметь не более одного обработчика завершения. В данном случае, даже если рекомендация по последовательному использованию сценариев выполняется, существует, по крайней мере, два возможных пути, с разной эффективностью. Первый вариант (25 переходов, соответствует порядку CKUO): [0], [1, 0], [2, 0, 0], [1, 0], [0], [1, 0], [1, 1], [2, 1, 0], [1, 1], [0], [1, 0], [2, 0, 0], [2, 1, 0], [2, 1, 1], [1, 1], [2, 1, 0], [2, 0, 0], [2, 0, 1], [1, 0], [2, 0, 0], [2, 0, 1], [2, 1, 1], [2, 1, 0], [2, 1, 1], [2, 0, 1], [2, 0, 0]. Второй вариант (27 переходов, соответствует порядку OKUC): [0], [1, 0], [0], [1, 0], [1, 1], [1, 0], [2, 0, 0], [1, 0], [1, 1], [0], [1, 0], [2, 0, 0], [2, 1, 0], [2, 0, 0], [2, 0, 1], [2, 0, 0], [2, 1, 0], [1, 1], [2, 1, 0], [1, 1], [2, 1, 0], [2, 1, 1], [2, 1, 0], [2, 1, 1], [2, 0, 1], [1, 0], [2, 0, 0], [2, 0, 1], [2, 1, 1], [1, 1]. Следствие из рассмотренных примеров. Разница в эффективности, показанная в данных примерах невелика, что обусловлено простотой модели (малое количество состояний и дуг), а также оптимальностью последовательного использования сценариев. Разница достигается исключительно за счет изменения расположения сценариев в обойме обходчика. Это указывает на необходимость анализа работы обходчика и применения результатов этого анализа при разработке модели, а также тестовых сценариев.

Краткое описание обходчиков UniTESK


В настоящий момент CTesK [], один из инструментов, поддерживающих разработку тестов по технологии UniTESK, включает два обходчика, реализующих различные алгоритмы построения обхода графов и имеющих различные ограничения на вид графов, с которыми они могут работать.

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

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

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

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

Литература


1.В. В. Кулямин, А. К. Петренко, А. С. Косачев, И. Б. Бурдонов. Подход UniTesK к разработке тестов. Программирование, т. 29, № 6, стр. 25-43, 2003.
2.А. В. Баранцев, И. Б. Бурдонов, А. В. Демаков, С. В. Зеленов, А. С. Косачев, В. В. Кулямин, В. А. Омельченко, Н. В. Пакулин, А. К. Петренко, А. В. Хорошилов. Подход UniTesK к разработке тестов: достижения и перспективы. Труды Института системного программирования РАН, т. 5, стр. 121-156, 2005.
3.http://www.opengroup.org/onlinepubs/007908799/xsh/threads.html
4.http://www.opengroup.org/onlinepubs/009695399/
functions/pthread_cleanup_pop.html
5.http://www.unix.org/version3/
6.http://www.unitesk.com/content/category/7/14/33/
7.И. Б. Бурдонов, А. С. Косачев, В. В. Кулямин. Использование конечных автоматов для тестирования программ. Программирование, т. 26, № 2, стр. 61-73, 2000.
8.И. Б. Бурдонов, А. С. Косачев, В. В. Кулямин. Неизбыточные алгоритмы обхода ориентированных графов: детерминированный случай. Программирование, т. 29, № 5, стр. 59-69, 2003.
9.http://www.unitesk.com/content/category/8/20/54/
10.И. Б. Бурдонов, А. С. Косачев, В. В. Кулямин. Неизбыточные алгоритмы обхода ориентированных графов: недетерминированный случай. Программирование, т. 30, № 1, стр. 2-17, 2004.
11.А. В. Хорошилов. Отчет о научно-исследовательской работе. Алгоритм обхода недетерминированных графов, обладающих детерминированным полным остовным подграфом. Шифр РИ-19.0/002/216.
12.http://www.structur.h1.ru/derevo.htm
1(обратно)Соответствует второму варианту из в разделе .
2(обратно)Соответствует первому варианту из в разделе .



Обход дерева


Сравним эффективность обходчиков при обходе полного бинарного дерева высотой N, с операциями «опуститься на уровень ниже влево», «опуститься на уровень ниже вправо» и «подняться на уровень выше».

Теоретическая оценка длины обхода снизу равна количеству дуг 2N+2-4. Эта оценка может быть достигнута, например, при обходе в симметричном порядке [].

В Таблице 2 приведены длины обходов и время их выполнения для разных обходчиков.

N dfsm, длина dfsm, время ndfsm, длина ndfsm, время мин. длина
9 4088 6 2044 3 2044
10 8184 25 4092 12 4092
11 16376 100 8188 45 8188
12 32760 427 16380 19016380

Таблица 2. Длина и время обхода дерева для разных N.

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

Обход полного графа и его модификаций


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

Полный ориентированный граф с N вершинами, обозначаемый KN.

Граф KM(KN), представляющий собой соединенные с помощью KM M полных графов KN. Вершины этих M графов пронумерованы числами от 0 до (N-1) и все вершины с номером 0 соединены между собой полным графом.

Граф KM KN, являющийся декартовым произведением полных графов. Он тоже представляется как M графов KN с пронумерованными вершинами, в которых всем вершинам с одинаковыми номерами соединены друг с другом.

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

Числа N и M выбраны нечетными, потому что для полного графа с нечетным количеством вершин существует эйлеров цикл.

Теоретическая оценка длины обхода KN снизу равна количеству его дуг E(KN)=N × (N - 1).

Граф dfsm, длинаdfsm, времяndfsm, длинаndfsm, времямин. длина
K3 14 0 8 0 6
K5 60 0 24 0 20
K7 154 0 48 0 42
K51 46750 9 2600 1 2550
K53 52364 11 2808 1 2756
K55 58410 12 3024 1 2970
K57 64904 13 3248 1 3192
K59 71862 15 3480 1 3422
K61 79300 17 3720 1 3660

Таблица 3.Длина и время обходов полных графов.

Отметим тот факт, что обходчик ndfsm проходит на (N-1) дуг больше, чем нужно по минимуму для обхода полного графа KN.

Оценка длины обхода графа KM(KN) снизу тоже равна количеству его дуг
E(KM(KN)) = M × E(KN) + E(KM) = M × N × (N - 1) + M × (M - 1).

Графdfsm, длинаdfsm, времяndfsm, длинаndfsm, времямин. длина
K3(K51) 140264 29 7810 2 7656
K5(K51) 233810 53 13028 3 12770
K7(K51) 327404 80 18254 5 17892
K3(K53) 157106 35 8434 2 8264
K5(K53) 261880 60 14068 4 13800
K7(K53) 366702 94 19710 6 19334
K3(K55) 175244 40 9082 2 8916
K5(K55) 292110 71 15148 4 14870
K7(K55) 409024 108 21222 6 20832

Таблица 4. Длина и время обходов графов KM(KN).

Отметим, что длина обхода этих графов с помощью dfsm может быть вычислена по той же формуле, что и количество дуг: если D(G) обозначает длину обхода графа G с помощью dfsm, то


D(KM(KN))=M × D(KN) + D(KM). Можно предположить, что при обходе графа, состоящего из нескольких слабо связанных (при помощи одной-двух дуг) частей, длина его обхода получается сложением длин обходов частей и количества проходов по связывающим дугам. Оценка длины обхода графа KM KN снизу также равна количеству его дуг
E(KM × KN) = M × E(KN) + N × E(KM) = M × N × (N + M - 2).

Графdfsm, длинаdfsm, времяndfsm, длинаndfsm, времямин. длина
K3× K51 269265 62 8108 1 7956
K5× K51 804614 186 14024 5 13770
K7× K51 1694413 406 20348 5 19992
K3× K53 301095 68 8744 2 8576
K5× K53 898884 216 15104 4 14840
K7× K53 1890675 302 21888 5 21520
K3× K55 335337 50 9404 2 9240
K5× K55 1000234 164 16224 3 15950
K7× K55 2101501 365 23484 5 23100
Таблица 5. Длина и время обходов графов KM KN. Теперь длина обхода с помощью dfsm уже не может быть определена с помощью аналогичной формулы. Приведенные таблицы показывают, что на многих графах обходчик ndfsm работает эффективнее dfsm, и, если проверка детерминизма графа не является необходимым элементом тестирования, предпочтительнее использовать первый обходчик. Можно заметить, что при увеличении количества дуг длина обхода с помощью dfsm составляет порядка 50% от произведения количества дуг на количество состояний, что означает практическую невозможность использования dfsm-обходчика в случае насыщенных графов с сотнями состояний.

Сфера применения тестирования на основе спецификаций


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

Рассмотрим преимущества подхода тестирования на основе спецификаций, на примере технологии UniTESK. Абстрагирование от архитектуры.
Независимость тестов от внутренней архитектуры реализации становится возможной, благодаря отделению кода спецификации от медиаторов.
В результате спецификации обладают самостоятельной ценностью. При переходе от одной архитектуры реализации к другой может потребоваться изменение медиаторов, логика же тестирования остается неизменной. Разработчику тестов для системы, работающей на специфической платформе достаточно иметь спецификации и интерфейс реализации: они однозначно определяют построение медиаторной части. Конфигурационная система.
Благодаря разделению спецификаций и реализационно-зависимых компонентов теста, возникает возможность создания гибкой конфигурационной системы, способной адекватно отражать в спецификациях неописанные варианты поведения функций. В частности, это относится к тем случаям, когда поведение тестируемой функции сильно зависит от специфики конкретной реализации (implementation-defined). Генерация отчета по покрытию проверенных требований работы функции.
Такие отчеты, помимо оценки качества тестирования, дают возможность выделить часто используемые части программы, для их возможной дальнейшей оптимизации. Разделение сценариев и спецификаций.
Такое разделение позволяет использовать одно описание функциональности тестируемой системы при ее тестировании в различных условиях.
Например, сценарии легко дорабатываются в следующих направлениях. Увеличение множества тестовых значений параметров функции.
Это приводит к более полному тестированию функции. Обычно для минимальной полноты тестов требуется по одному набору значений параметров на каждую ветвь функциональности, определенную в спецификации данной функции. Вовлечение в тестирование функции связанных с ней функций.
Этот метод также приводит к более полному тестированию реализации функции.
Особенно он важен при тестировании функций со скрытым состоянием, на которое можно влиять исключительно опосредованно, путем вызова других функций.

Сравнение эффективности обходчиков UniTESK


, Российско-Армянский (Славянский) государственный университет, Ереван, Армения
Труды Института системного программирования РАН

В данном разделе приводятся экспериментальные данные о сравнительной эффективности двух обходчиков CTesK.

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

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

При сравнении использовался компьютер с процессором AMD 3200+, 1024 MB памяти.

В настоящее время тестирование на


В настоящее время тестирование на основе моделей получает все большее распространение. Используемые в его ходе модели могут быть более абстрактными, чем реализация, но в то же время они хорошо отражают основные особенности тестируемой системы. Относительно небольшой размер моделей позволяет реализовать их автоматическую обработку, а подобие модели тестируемой системе гарантирует, что тесты, сгенерированные на основе модели, позволят провести ее систематическое тестирование. Кроме того, тесты, построенные на основе моделей, легче сопровождать и проще переиспользовать из-за их более высокого уровня абстракции и независимости от реализации. Одним из наиболее успешных примеров применения подхода тестирования на основе моделей является технология UniTESK [,], разработанная в Институте Системного Программирования РАН. В рамках этой технологии математические модели используются для решения основных задач тестирования: оценки корректности поведения целевой системы, генерации тестовых данных, тестовых последовательностей и оценки качества тестирования. Генерация тестовой последовательности в технологии UniTESK производится на основе построения обхода графа, выступающего в качестве абстрактной модели тестируемой системы и отражающего выделенные разработчиком тестов аспекты ее поведения. Уникальной особенностью технологии UniTESK является задание графа модели в неизбыточном виде. Это означает, что перед началом тестирования о графе ничего не известно и вся информация о нем появляется только в процессе тестирования. Таким образом, граф может не только задаваться в виде статической модели тестируемой системы, но и строиться динамически, в результате наблюдений за поведением тестируемой системы во время тестирования. Извлечение модели тестируемой системы в процессе выполнения теста позволяет добиться существенного улучшения качества тестирования, масштабируемости тестового набора и упрощения переиспользования тестовых сценариев. Для обеспечения этих преимуществ все используемые алгоритмы работы с графом должны учитывать тот факт, что информация о графе появляется только во время выполнения теста. Основными понятиями технологии UniTESK являются понятия спецификации, медиатора, тестового сценария и обходчика. Спецификация представляет собой описание формальной модели тестируемой функции. Медиатор осуществляет взаимодействие спецификации (формальной модели) и реализации тестируемой функции. Тестовый сценарий представляет собой неизбыточное описание графа, моделирующего тестовую систему, и состоит из набора сценарных функций и функции вычисления текущего состояния - вершины графа. Каждая сценарная функция представляет совокупность однотипных тестовых воздействий. Обходчик, основываясь на тестовом сценарии, осуществляет перебор всех допустимых тестовых воздействий во всех достижимых состояниях задаваемого этим сценарием графа. Целью данной работы является исследование эффективности алгоритмов обходчиков, входящих в инструмент CTesK, результаты которого позволят дать рекомендации по построению тестовых сценариев в условиях ограниченных ресурсов.

Моделирование поведения практически важной системы


Моделирование поведения практически важной системы в виде конечного автомата часто приводит к большому числу состояний и переходов в итоговой модели. При тестировании такой системы с помощью технологии UniTESK выполняется автоматическое построение обхода графа состояний и переходов модели. Длина такого обхода в значительной степени зависит от используемого алгоритма обходчика. В работе было проведен сравнительный анализ эффективности построения обхода графов с помощью обходчиков dfsm и ndfsm, входящих в инструмент CTesK. Полученные результаты показывают, что для многих графов второй обходчик строит существенно более короткие обходы, и, соответственно, позволяет получать тесты, работающее значительно быстрее, но обеспечивающие те же значения тестового покрытия. Кроме того, показана возможность некоторого уменьшения времени работы теста только за счет изменения очередности задания сценарных функций.

Зависимость работы обходчика от порядка сценарных функций


В Таблице 1 показано количество переходов, выполняемое обходчиками для построения обхода графов из раздела 3 при различных упорядочениях сценарных функций. C в этой таблице обозначает операцию создания нового потока, K - уничтожение одного из имеющихся потоков, U - помещение функции в стек обработчиков завершения потока, O - выталкивание функции из этого стека.

Порядок сценарных функций Простой пример (Рис. 2)
Количество состояний - 4.
Количество дуг - 8.Сложный пример (Рис. 3)
Количество состояний - 7.
Количество дуг - 13.
ndfsm dfsm ndfsm dfsm
CKUO 16 22 31 76
CKOU 16 22 29 76
CUKO 16 25 29 76
CUOK 13 25 27 88
COKU 16 19 30 88
COUK 13 25 27 88
KCUO 16 22 31 68
KCOU 16 22 29 68
KUCO 16 22 30 60
KUOC 16 22 30 60
KOCU 16 22 31 68
KOUC 16 22 31 59
UCKO 16 25 29 64
UCOK 13 25 27 69
UKCO 16 25 29 60
UKOC 16 25 29 60
UOCK 13 25 27 69
UOKC 16 25 31 69
OCKU 16 19 30 88
OCUK 13 25 27 88
OKCU 16 19 30 61
OKUC 16 19 31 55
OUCK 13 25 27 68
OUKC 16 25 31 68

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

Таблица 1 показывает, что, меняя только порядок обращений к сценарным функциям, можно добиться следующего ускорения более 35% для dfsm (сложный пример, сравнение CUOK и OKUC) и более 10% для ndfsm (сложный пример, CKUO и CUOK).

На рассмотренных примерах ndfsm демонстрирует более высокую производительность. Далее мы рассмотрим дополнительные примеры, подтверждающие это.

Планирование тестов


Первый вопрос, который встает перед нами: «Сколько нужно тестов». Ответ, который часто дается: тестов должно быть столько, чтобы не осталось неоттестированных участков. Можно даже ввести формальное правило:

Код с не оттестированными участками не может быть опубликован

Проблема в том, что хотя неоттестированный код почти наверняка неработоспособен, но полное покрытие не гарантирует работоспособности. Написание тестов исходя только из уже существующего кода только для того, чтобы иметь стопроцентное покрытие кода тестами — порочная практика. Такой подход со всей неизбежностью приведет к существованию оттестированного, но неработоспособного кода. Кроме того, метод белового ящика, как правило, приводит к созданию позитивных тестов. А ошибки, как правило, находятся негативными тестами. В тестировании вопрос «Как я могу сломать?» гораздо эффективней вопроса «Как я могу подтвердить правильность?». Это наглядно демонстрирует статья 61 тест, который потряс программу.

В первую очередь тесты должны соответствовать не коду, а требованиям. Правило, которое следует применять:

Тесты должны базироваться на спецификации.

Пример такого подхода можно посмотреть в статье Тривиальная задача.

Один из эффективных инструментов, для определения полноты тестового набора — матрица покрытия.

На каждое требование должен быть, как минимум, один тест. Неважно, ручной или автоматический.

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

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

Последнюю проверку полноты тестового набора следует проводить с помощью формальной метрики «Code Coverage». Она показывает неполноту тестового набора. И дальнейшие тесты можно писать на основании анализа неоттестированных участков.

Наиболее эффективный способ создания тестового набора — совместное использование методов черного и белого ящиков.

Распределение обязанностей


Где-то я читал следующую фразу: «Попросите программиста составить для вас (тестера) план тестов». А потом тестер будет кодировать тесты. Генеральный директор рисовать дизайн, а администратор баз данных писать руководство пользователя. Не очень воодушевляющая картина.

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

Задача Требуемые навыки Роль
Определение методов обеспечения качества ПО Отличное знание теории тестрования Ведущий тестировщик проекта
Создание тестов Хорошее знание методов тестирования Дизайнер тестовых сценариев
Кодирование тестов Средние навыки программирования Программист автоматических тестов
Выполнение тестов Знание среды выполнения тестов Тестер

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

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

Стратегия модульного тестирования


Модульное тестирование является одной из ключевых практик методологии экстремального программирования. Сторонники XP приводят следующие доводы в защиту этой практики:

Написание тестов помогает войти в рабочий ритм Придает уверенность в работоспособности кода. Дает запас прочности при дальнейшей интеграции или изменениях кода.

Согласен, вхождение в рабочий ритм — благородная задача. Уверенность в работоспособности — тоже хорошо. Но «уверенности в работоспособности» я предпочитаю действительно работоспособный код. Пусть даже при этом я не совсем «уверен».

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

Известно, что продукт оптимальный по набору бюджет/функциональность/качество получается при применении различных способов обеспечения качества. Бездумное применение тотального модульного тестирования почти гарантированно приведет к получению неоптимального продукта. И никакие «запасы прочности» и «быстрый вход в рабочий ритм» не спасут проект от провала.

На мой взгляд, модульное тестирование оправдано, если оно:

Снижает время на отладку Дает возможность поиска ошибок с меньшими затратами, нежели при других подходах Дает возможность дешевого поиска ошибок при изменениях кода в дальнейшем

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

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

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

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

Терминология


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

Unit (Элемент) — наименьший компонент, который можно скомпилировать.

Драйверы — модули тестов, которые запускают тестируемый элемент.

Заглушки — заменяют недостающие компоненты, которые вызываются элементом и выполняют следующие действия:

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

White-box testing. Для конструирования тестов используются внутренняя структура кода и управляющая логика. При этом существует вероятность, что код будет проверяться так, как он был написан, а это не гарантирует корректность логики.

Black-box testing. Для конструирования тестов используются требования и спецификации ПО. Недостатки:

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

Аннотация.


Данная статья излагает базовые принципы технологии разработки тестов UniTesK, основанной на использовании формальных моделей тестируемого программного обеспечения (ПО). Кроме того, излагается опыт использования этой технологии для тестирования ПО разных видов, описываются проблемы внедрения в промышленность, свойственные всем технологиям, основанным на формальных методах, и формулируются возможные пути их решения. Технология UniTesK была разработана в группе спецификации, верификации и тестирования [RedVerst] ИСП РАН на основе многолетнего опыта проведения проектов верификации и тестирования сложного промышленного ПО.

Статья содержит материал, который заинтересует как исследователей в области формальных методов, так и практиков, которые хотели бы ознакомиться с потенциалом тестирования на основе моделей в реальных крупномасштабных приложениях. Читателям из последней группы рекомендуется после разделов "Основные принципы UniTesK" и "Процесс построения тестов по UniTesK" перейти к разделу "Опыт использования UniTesK", а затем выбрать те разделы, которые покажутся им интересными.



Критерии тестового покрытия, основанные на спецификациях


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

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

Отталкиваясь от определения ветвей функциональности в постусловии, можно автоматически извлечь более детальные критерии покрытия, основанные на структуре ветвлений в пред- и постусловиях. Наиболее детальным является критерий покрытия дизъюнктов. Он определяется всеми возможными комбинациями значений элементарных логических формул, использованных в ветвлениях. Этот критерий является аналогом критерия MC/DC [MCDC] для покрытия кода.

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

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



Литература


[ADLt] M. Obayashi, H. Kubota, S. P. McCarron, and L. Mallet. The Assertion Based Testing Tool for OOP: ADL2, available via [AGEDIS] I. Gronau, A. Hartman, A. Kirshin, K. Nagin, and S. Olvovsky. A Methodology and Architecture for Automated Software Testing. Available at [AGEDISW] [ASMB] E. Borger and R. Stark. Abstract State Machines: A Method for High-Level System Design and Analysis. Springer-Verlag, 2003. [ASMI] Y. Gurevich. Evolving Algebras: An Attempt to Discover Semantics. In Current Trends in Theoretical Computer Science, eds. G. Rozenberg and A. Salomaa, World Scientific, 1993, pp. 266-292. [ASMT] W. Grieskamp, Y. Gurevich, W. Schulte, and M. Veanes. Testing with Abstract State Machines. In R. Moreno-Diaz and A. Quesada-Arencibia, eds., Formal Methods and Tools for Computer Science (Proceedings of Eurocast 2001), Universidad de Las Palmas de Gran Canaria, Canary Islands, Spain, February 2001, pp. 257-261. [ASMTW] [AsSM] И. Бурдонов, А. Косачев, В. Кулямин. Асинхронные автоматы: классификация и тестирование, Труды ИСП РАН, 4:7-84, 2003. [ASSUM] S. Fujiwara and G. von Bochmann. Testing Nondeterministic Finite State Machine with Fault Coverage. IFIP Transactions, Proceedings of IFIP TC6 Fourth International Workshop on Protocol Test Systems, 1991, Ed. by Jan Kroon, Rudolf J. Heijink, and Ed Brinksma, 1992, North-Holland, pp. 267-280. [ATS] http://www.atssoft.com [BP] G. v. Bochmann and A. Petrenko. Protocol Testing: Review of Methods and Relevance for Software Testing. In Proceedings of ACM International Symposium on Software Testing and Analysis. Seattle, USA, 1994, pp. 109-123. [CADPO] H. Garavel, F. Lang, and R. Mateescu. An overview of CADP 2001. INRIA Technical Report TR-254, December 2001. [CCNET] M. Barnett and W. Schulte. Contracts, Components, and their Runtime Verification on the .NET Platform. Technical Report TR-2001-56, Microsotf Research. [DBCA] Bertrand Meyer. Applying `Design by Contract'. IEEE Computer, vol. 25, No. 10, October 1992, pp. 40-51. [DBCE] Bertrand Meyer.
Bartetzko, C. Fisher, M. Moller, and H. Wehrheim. Jass - Java with assertions. In K. Havelund and G. Rosu, editors, Proceeding of the First Workshop on Runtime Verification RV'01, Vol. 55 of Electronic Notes in Theoretical Compter Science, Elsevier Science, July 2001. [JassW] [Jatva] Igor B. Bourdonov, Alexey V. Demakov, Andrew A. Jarov, Alexander S. Kossatchev, Victor V. Kuliamin, Alexander K. Petrenko, Sergey V. Zelenov. Java Specification Extension for Automated Test Development. Proceedings of PSI'01. LNCS 2244, pp. 301-307. Springer-Verlag, 2001. [jContr] M. Karaorman, U. Holzle, and J. Bruno. jContractor: A reflective Java library to support design by contract. Technical Report TRCCS98-31, University of California, Santa Barbara. Computer Science, January 19, 1999. [jContrW] [JISL] P. Muller, J. Meyer, and A. Poetzsch-Heffter. Making executable interface specifications more expressive. In C. H. Cap, editor, JIT'99 Java-Informations-Tage 1999, Informatik Aktuell. Springer-Verlag, 1999. [JML] A. Bhorkar. A Run-time Assertion Checker for Java using JML. Technical Report 00-08, Department of Computer Science, Iowa State University, 2000. [JMLW] [JMS] [JUNIT] [KORAT] C. Boyapati, S. Khurshid, and D. Marinov. Korat: Automated Testing Based on Java Predicates. Proc. of ISSTA 2002, Rome, Italy. Jul 2002. [KVEST] I. Bourdonov, A. Kossatchev, A. Petrenko, and D. Galter. KVEST: Automated Generation of Test Suites from Formal Specifications. FM'99: Formal Methods. LNCS 1708, Springer-Verlag, 1999, pp. 608-621. [LOTOS] ISO/IEC. Information Processing Systems - Open Systems Interconnection - LOTOS - A Formal Description Technique based on the Temporal Ordering of Observational Behaviour. ISO/IEC 8807:1989, International Organization for Standardization, Geneva, Switzerland, 1989. [Lustre] N. Halbwachs, P. Caspi, P. Raymond, and D. Pilaud. The synchronous data flow programming language LUSTRE. Proc. IEEE, vol. 79, pp. 1305-1320, Sept. 1991. [LY] D. Lee and M.


Yannakakis. Principles and Methods of Testing Finite-State Machines. A survey. Proceedings of the IEEE, Vol. 84, No. 8, 1996, pp. 1090-1123. [MCDC] J. J. Chilenski and S. P. Miller. Applicability of modified condition/decision coverage to software testing. Software Engineering Journal, pp. 193-200, September 1994. [MSRIPreport] [MulSaw] [Murphi] [NDFSM] И. Б. Бурдонов, А. С. Косачев, В. В. Кулямин. Неизбыточные алгоритмы обхода ориентированных графов. Недетерминированный случай. Программирование, 2003. В этом номере. [Manage] D.Stidolph, J.Whitehead. Managerial Issues for the Consideration and Use of Formal Methods, LNCS No.2805, 2003, pp.170-186.] [MDA] [OPT] A. Kossatchev, A. Petrenko, S. Zelenov, and S. Zelenova. Using Model-Based Approach for Automated Testing of Optimizing Compilers. In Proccedings of Intl. Workshop on Program Undestanding, Gorno-Altaisk, 2003. [ORA] L. Baresi and M. Young. Test Oracles. Tech. Report CIS-TR-01-02. Available at [PARASOFT] [Parnas] D. Peters and D. Parnas. Using Test Oracles Generated from Program Documentation. IEEE Transactions on Software Engineering, 24(3):161-173, 1998. [PROJ] G. Friedman, A. Hartman, K. Nagin, T. Shiran. Projected state machine coverage for software testing. Proc. of ISSTA 2002, Rome, Italy. Jul 2002. [RedVerst] [Robinson] H. Robinson. Obstacles and opportunities for model-based testing in an industrial software environment. In proceedings of 1-st ECMDSE, 2003 [SCR] C. Heitmeyer. Software Cost Reduction. Encyclopedia of Software Engineering, Two Volumes, John J. Marciniak, editor, ISBN: 0-471-02895-9, January 2002. [SDL] J. Ellsberger, D. Hogrefe, and A. Sarma, SDL - Formal Object-Oriented Language for Communicating Systems, Prentice Hall, 1997. [SDLt] C. Bourhfir, E. Aboulhamid, R. Dssouli, N. Rico. A test case generation approach for conformance testing of SDL systems. Computer Communications 24(3-4): 319-333 (2001). [SLIC] T. Ball and S. Rajamani. SLIC: A specification language for interface checking (of C).


Technical Report, MSR-TR-2001-21, Microsoft Research, January 2002. [TGV] J.-C. Fernandez, C. Jard, T. Jeron, and C. Viho. An experiment in automatic generation of test suites for protocols with verification technology. In Special Issue on Industrially Relevant Applications of Formal Analysis Techniques, J. F. Groote and M. Rem, editors, Elsevier Science publisher, 1996. [TorX] J. Tretmans, A. Belinfante. Automatic testing with formal methods. In EuroSTAR'99: 7th European Int. Conference on Software Testing, Analysis and Review, Barcelona, Spain, November 8-12, 1999. EuroStar Conferences, Galway, Ireland. Also: Technical Report TRCTIT-17, Centre for Telematics and Information Technology, University of Twente, The Netherlands. [TPA] J. Grabowski, D. Hogrefe, R. Nahm. Test case generation with test purpose specification by MSCs. In O. Faergemand and A. Sarma, editors, 6th SDL Forum, pages 253-266, Darmstadt, Germany, North-Holland 1993. [TPB] C. J. Wang, M. T. Liu. Automatic test case generation for Estelle. In International Conference on Network Protocols, pages 225-232, San Francisco, CA, USA, 1993. [TRover] [TRT] [TVEC] [UMBTG] E. Farchi, A. Hartman, and S. S. Pinter. Using a model-based test generator to test for standard conformance. IBM Systems Journal, volume 41, Number 1, 2002, pp. 89-110. [UML-TP] UML Testing Profile. [UniArch] I. Bourdonov, A. Kossatchev, V. Kuliamin, and A. Petrenko. UniTesK Test Suite Architecture. Proc. of FME 2002. LNCS 2391, pp. 77-88, Springer-Verlag, 2002. [UNITESK]

Описание функциональных требований


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

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

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

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


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

Определение связи спецификаций и реализации


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

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

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



UniTesK позволяет использовать доступную извне


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

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


Опыт использования UniTesK


Работы над инструментами для поддержки технологии UniTesK начались в конце 1999 года. К тому времени уже было проведено несколько проектов, где технология KVEST использовалась для разработки тестов и регрессионного тестирования крупных промышленных систем компании Nortel Networks, производителя цифрового телекоммуникационного оборудования. Примерами систем Nortel Networks, к которым применялся KVEST были:

Ядро операционной системы реального времени (размер около 250 тысяч строк, язык реализации ПРОТЕЛ, близок к С). Система хранения и быстрого поиска сообщений. Утилиты базисного уровня телефонных сервисов. Распределенная система управления сообщениями P2P.

Первой была готова для использования реализация UniTesK для программ на языке C - CTesK. Упрощенный вариант инструментов для поддержки этой технологии был готов к концу 2000 года. К середине 2001 они уже активно использовались в исследовательском проекте по гранту Microsoft Research. Целью проекта было тестирование реализации стека интернет-протоколов нового поколения. IPv6. Кроме того, ставилась задача проверки пригодности UniTesK для тестирования задач нового класса - реализаций телекоммуникационных протоколов. К концу 2001 года проект был завершен. Были найдены серьезные ошибки в реализации, способные привести к нарушению работы произвольного узла в сети на основе IPv6. Поскольку данная реализация тестировалась одновременно несколькими командами тестировщиков в разных странах мира, и никто не обнаружил этих ошибок, была показана высокая результативность UniTesK. В рамках данного проекта был впервые опробован новый механизм тестирования распределенных и асинхронных систем на основе автоматных моделей в виде IOSM.

В 2003 году был проведен пилотный проект применения CTesK для тестиро-вания ПО реального времени (алгоритмы управления навигационными устройствами, ГосНИИАС). Несмотря на сжатые сроки проекта удалось найти серьезную ошибку в алгоритме. В середине 2002 года была готова первая коммерческая версия инструмента J@T, инструмента разработки тестов для Java программ .
Основное же их преимущество в том, что они позволяют автоматически построить оракулы [Parnas,KVEST,ADLt], проверяющие соответствие поведения целевой системы спецификациям, и критерии тестового покрытия, которые достаточно близки к критериям покрытия требований.

Практически невозможно обеспечить универсальный механизм построения единичных тестовых воздействий (например, вызовов операций с разными наборами аргументов), который был бы достаточно эффективен как по времени, затраченному на тестирование, так и с точки зрения достижения высокого тестового покрытия. В то же время, довольно просто построить итератор, перебирающий большое множество значений некоторого типа. Инструменты, поддерживающие UniTesK, предоставляют пользователям библиотеки базовых итераторов значений простых типов, которые могут быть непосредственно использованы для генерации тестовых воздействий, а могут быть скомпонованы в более сложные генераторы. Для уменьшения затрат времени на тестирование сгенерированные тестовые воздействия можно фильтровать, отбрасывая те и них, которые не увеличивают достигнутый уровень покрытия. Фильтры для этого генерируются автоматически из определения критерия тестового покрытия (см. пункт 6).

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



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

Чтобы обеспечить более удобную интеграцию в существующие процессы разработки, UniTesK может использовать для представления спецификаций и тестовых сценариев расширения широко используемых языков программирования, построенные на основе единой системы понятий (хотя классические языки формальных спецификаций тоже могут использоваться). Такое представление делает спецификации и сценарии понятнее для обычного разработчика ПО и позволяет сократить срок освоения основных элементов технологии до одной недели. Сразу после этого обучения разработчик тестов может использовать UniTesK для получения практически значимых результатов. Кроме того, использование расширений известных языков программирования вместо специального языка значительно облегчает интеграцию тестовой и целевой систем, необходимую для проведения тестирования. На данный момент в ИСП РАН разработаны инструменты, поддерживающие работу по технологии UniTesK с использованием расширений Java, C и C#.

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



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

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


Подход UniTesK к разработке тестов: достижения и перспективы


А.В. Баранцев, И.Б. Бурдонов, А.В. Демаков, С.В. Зеленов, А.С. Косачев, В.В. Кулямин, В.А. Омельченко, Н.В. Пакулин, А.К. Петренко, А.В. Хорошилов
Труды



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


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

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

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

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

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

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

Сценарий может определять состояния описываемой автоматной модели, осно-вываясь не только на модельном состоянии, описанном в спецификациях, но и учитывая какие-то аспекты реализации, не нашедшие отражения в специфи-кациях. С другой стороны, можно также абстрагироваться от каких-то деталей в спецификациях, уменьшая тем самым число состояний в результирующей модели (см. [FACTOR]). Таким образом, способ построения теста может варьироваться независимо от спецификаций, и, следовательно, независимо от механизма проверки корректности поведения при единичном воздействии. Тестовые сценарии можно разрабатывать вручную, но в большинстве случаев они могут быть сгенерированы при помощи интерактивного инструмента, шаблона построения сценариев, который запрашивает у пользователя только необходимую информацию, и может использовать разумные умолчания.


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

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

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

Без спецификаций асинхронных реакций можно тестировать системы, удовлетворяющие аксиоме чистого параллелизма (plain concurrency axiom): результат параллельного выполнения любого набора вызовов операций такой системы такой же, как при выполнении того же набора вызовов в некотором порядке. Для систем, не удовлетворяющих этой аксиоме, можно ввести дополнительные "срабатывания", соответствующие выдаче асинхронных реакций или внутренним, не наблюдаемым извне, изменениям состояния системы, таким образом, что полученная модель уже будет "чистой" (plain).

Автоматные модели, используемые для тестирования таких систем, являются некоторым обобщением автоматов ввода/вывода [IOSMA]. При проведении тестирования "чистой" системы используется следующий метод проверки корректности ее поведения.


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

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

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


Процесс построения тестов по UniTesK


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

1. Анализ функциональных требо-ваний к целевому ПО на основе имеющихся документов или знаний участников проекта, запись требований в виде формальных спецификаций.
2. Формулировка требования к качеству тестирования - какой уровень тестового покрытия будет считаться достаточным, чтобы прекратить тестирование.
3. Разработка набора тестовых сценариев, обеспечивающего достижение нужного уровня покрытия. Сценарии разрабатываются на основе спецификаций и не привязаны к конкретной реализации целевого ПО или его конкретной версии.
4. Привязка полученных тестовых сценариев к конкретной реализации целевой системы. Для этого надо разработать набор медиаторов.
5. Получение готовой к исполне-нию тестовой программы. Для того нужно оттранслировать спецификации, медиаторы и сценарии с расширения языка программирования в целос-тную тестовую систему на целевом языке программи-рования и скомпилировать ее.
6. Выполнение тестовой прог-раммы, возможно, отладка спецификаций, медиаторов и тестовых сценариев.
7. Анализ результатов, а именн,о анализ полноты тестового пок-рытие и принятие решения и продолжении или прекра-щении тестирования. Оформ-ление описания ошибок.

Представленная ниже, на Рис. 2, схема показывает процесс получения основных компонентов архитектуры тестового набора по технологии UniTesK.

Рис. 2. Получение компонентов теста по UniTesK.

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



Сравнение с другими подходами к разработке тестов на основе моделей


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

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

Имеющиеся подходы к разработке тестов, в основном, используют стандартную, сложившуюся еще несколько десятилетий назад архитектуру теста. Тест в ней представляет собой набор тестовых вариантов (test cases), каждый из которых служит для проверки некоторого свойства целевой системы в определенной ситуации. В UniTesK тесты строятся в виде сценариев, каждый из которых, по существу, исполняет роль целого набора тестовых вариантов, проверяющих работу целевой системы при обращении к выделенной группе интерфейсов в различных ситуациях. В результате, в тестовом наборе UniTesK больше уровней иерархии, что удобно при тестировании больших и сложных систем. С другой стороны, тестовые варианты позволяют более эффективно воспроизводить нужные ситуации при повторном тестировании, например, на наличие ранее обнаруженной ошибки. Для регрессионного тестирования обе схемы пригодны в равной степени, поскольку при этом обычно требуется возможность прогона всего набора тестов.

Автоматическое построение тестовых оракулов на основе спецификаций отличает UniTesK от инструментов, таких как JUnit [JUNIT], автоматизирующих только выполнение тестов. Вместе с тем, оно поддерживается очень многими существующими инструментами, например, следующими:

iContract [iContract,iContractW], JMSAssert [JMS], JML [JML,JMLW], jContractor [jContr,jContrW], Jass [Jass,JassW], Handshake [Handshake], JISL [JISL] используют контрактные спецификации, написанные в исходном коде целевой системы в виде комментариев на расширении Java (обзоры таких систем можно найти в [CCNET] и [ORA] ) SLIC [SLIC] позволяет оформлять контрактные спецификации на расширении C с использованием предикатов временных логик Test RealTime [TRT] от Rational/IBM использует контракты и описание структуры конечно-автоматной модели целевого компонента в виде специальных скриптов JTest/JContract [PARASOFT] от Parasoft и Korat [KORAT] позволяют писать предусловия, постусловия и инварианты в виде особых комментариев в Java-программах ATG-Rover [TRover] использует спецификации в виде программных контрактов-комментариев на С, Java или Verilog, которые могут содержать предикаты временных логик LTL или MTL Семейство инструментов ADL [ADLt] основано на расширениях С, С++, Java и IDL, которые используются для разработки контрактных спецификаций, не привязанных жестко к конкретному коду T-VEC [TVEC] использует пред- и постусловия, оформленные в виде таблиц в нотации SCR [SCR]

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

Инструмент Korat является одним из инструментов, разработанных в рамках проекта MulSaw [MulSaw] лаборатории информатики MIT. Он использует контракты, оформленные на JML, для генерации множества наборов входных данных одного метода в классе Java, включая и сам объект, в котором данный метод вызывается, гарантирующего покрытие всех логических ветвлений в спецификациях. Таким образом, вместо построения тестовой последовательности можно сразу получить целевой объект в нужном состоянии. С другой стороны, спецификации должны быть жестко привязаны к реализации. В частности, они не должны не допускать таких состояний целевого компонента, которые не могут возникнуть в ходе его работы, иначе много сгенерированных тестов будут соответствовать недостижимым состояниям компонента.

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

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


Генерация тестовых последовательностей не поддерживается.

Кроме T-VEC, нам не известны инструменты, поддерживающие, подобно UniTesK, генерацию тестов, нацеленных на достижение высокого покрытия по критериям, построенным по внутренней структуре контрактных спецификаций. Большинство имеющихся инструментов способно отслеживать покрытие спецификаций только как процент операций, которые были вызваны. Генерация тестовых последовательностей поддерживается многими инструментами, использующими модели целевой системы в виде различного рода автоматов: расширенных конечных автоматов, взаимодействующих конечных автоматов, автоматов ввода/вывода, систем помеченных переходов, сетей Петри и пр. Такие инструменты хорошо подходят для верификации телекоммуникационного ПО, при разработке которого зачастую используются формальные языки спецификаций, основанные на перечисленных представлениях ПО --- SDL [SDL,ITUSDL,ITUSDLN], LOTOS [LOTOS], Estelle [Estelle], ESTEREL [ESTEREL,ESTERELL] или Lustre [Lustre]. Большинство этих инструментов использует в качестве спецификаций описание поведения системы на одном из указанных языков, трансформируя его в автоматную модель нужного вида.

Часть таких инструментов использует, помимо спецификаций поведения системы, сценарий тестирования, называемый обычно целью теста (test purpose) и заданный пользователем в виде последовательности сообщений, которой обмениваются компоненты ПО (MSC), или небольшого автомата (см., например, [TPA,TPB,CADPO,TGV]). Другая часть использует явно описанные автоматные модели для генерации тестовых последовательностей, нацеленных на достижение определенного уровня покрытия согласно какому-либо критерию (см. [TorX,SDLt,EST]). UniTesK, как уже говорилось, поддерживает построение тестовых последовательностей и из заданных пользователем сценариев, и на основе автоматной модели системы, интегрируя оба подхода.

Наиболее близки к UniTesK по поддерживаемым возможностям инструменты GOTCHA-TCBeans [UMBTG,GOTCHA] (один из инструментов генерации тестов, объединяемых в рамках проекта AGEDIS [AGEDIS,AGEDISW]), и AsmL Test Tool [ASMT,ASMTW].


Оба они используют автоматные модели целевого ПО. Для GOTCHA-TCBeans такая модель должна быть описана на расширении языка Murphi [Murphi], AsmL Test Tool использует в качестве спецификаций описание целевой системы как машины с абстрактным состоянием (abstract state machine, ASM, см. [ASMI,ASMB]).

Объединяет все три подхода использование разных видов моделей для построения теста, что позволяет строить более эффективные, гибкие и масштабируемые тесты, а также иметь больше компонентов для повторного использования. В UniTesK это модель поведения в виде спецификаций и модель тестирования в виде сценария, в GOTCHA-TCBeans и других инструментах проекта AGEDIS, - автоматная модель системы и набор тестовых директив, управляющих процессом создания тестов на ее основе, в последних версиях AsmL Test Tool - ASM-модель системы и множество наблюдаемых величин, наборы значений которых определяют состояния конечного автомата, используемого для построения тестовой последовательности.

В указанных инструментах используются техники уменьшения размера модели, аналогичные факторизации в UniTesK. Инструмент GOTCHA-TCBeans может применять частный случай факторизации, при котором игнорируются значения некоторых полей в состоянии исходной модели [PROJ]. AsmL Test Tool может строить тестовую последовательность на основе конечного автомата, состояния которого получаются редукцией полного состояния машины до набора значений элементарных логических формул, используемых в описании ее переходов [FfASM].

Основными отличиями UniTesK от GOTCHA-TCBeans и AsmL Test Tool являются поддержка расширений языков программирования для разработки спецификаций, использование контрактных спецификаций, автоматизация отслеживания покрытия спецификаций и использование фильтров для получения тестовых воздействий, нацеленных на его повышение.


Универсальная архитектура теста


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

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

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

Архитектура теста UniTesK [UniArch] основана на следующем разделении задачи тестирования на подзадачи:

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

Для решения каждой из этих задач предусмотрена технологическая поддержка.

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

Такие оракулы легко строятся из спецификаций программного контракта в виде пред- и постусловий интерфейсных операций и инвариантов типов, формулирующих условия целостности данных [KVEST,ADLt]. При таком подходе каждое возможное воздействие моделируется как обращение к одной из интерфейсных операций с некоторым набором аргументов, а ответ системы на него - в виде результата этого вызова. Далее будут более детально рассмотрены специфика моделирования асинхронных реакций целевой системы и используемые техники специфицирования.

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

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

Для построения последовательности тестовых воздействий используется конечно-автоматная модель системы. Конечные автоматы достаточно просты, знакомы большинству разработчиков и могут быть использованы для моделирования практически любой программы. Для тестирования парал-лелизма или распределенных систем используется разновидность автоматов ввода/вывода [IOSMA], в которых переходы помечаются только входным или только выходным символом.


Итоговый конечный автомат представлен в виде итератора тестовых воздействий. Этот компонент имеет интерфейс для получения идентификатора текущего состояния, получения идентификатора очередного воздействия, допустимого в данном состоянии, и для выполнения воздействия по его идентификатору.

Подробнее об используемых автоматных моделях для тестирования параллелизма можно прочитать в [AsSM].

Тестовая последовательность строится во время тестирования динамически, за счет построения некоторого "исчерпывающего" пути по переходам автомата. Это может быть обход всех его состояний, всех его переходов, всех пар смежных переходов и т.п. Алгоритм построения такого пути на достаточно широком классе автоматов оформлен в виде другого компонента теста, обходчика.

Удобное для человека описание используемой при тестировании конечно-автоматной модели мы называем тестовым сценарием. Из тестового сценария генерируется итератор тестовых воздействий. Сценарии могут разрабатываться вручную, но для многих случаев достаточно сценариев, которые можно получить автоматически на основе набора спецификаций операций, указания целевого критерия покрытия, способа итерации параметров операций и способа вычисления идентификатора состояния. Более детально методы построения тестовых последовательностей рассматриваются ниже, в соответствующем подразделе. Обходчики нескольких разных видов предоставляются в виде библиотечных классов, и пользователю нет нужды разрабатывать их самому. Для того, чтобы использовать в тестировании спецификации, написанные на более высоком уровне абстракции, чем сама целевая система, UniTesK предоставляет возможность использовать медиаторы. Медиатор задает связь между некоторой спецификацией и конкретной реализацией соответствующей функциональности. При этом он определяет преобразование модельных представлений воздействий (вызовов модельных операций) в реализационное, и обратное преобразование реакций целевой системы в их модельное представление (результат, возвращаемый модельной операцией).



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



Рис. 1. Архитектура теста UniTesK.

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


Универсальное расширение языков программирования


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

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

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

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

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

Java
specification package example; class SqrtSpecification { specification static double sqrt ( double x ) reads x, epsilon { pre { return x >= 0; } post { if(x == 0) { branch "Zero argument"; return sqrt == 0; } else { branch "Positive argument"; return sqrt >= 0 && Math.abs((sqrt*sqrt-x)/x) Декларация
пакета Декларация класса Сигнатура операции Описание доступа
на чтение/запись Предусловие Постусловие Определение ветви
функциональности Ограничения
на результат Определение ветви
функциональности Ограничения
на результат
C#
namespace Examples { specification class SqrtSpecification { specification static double Sqrt ( double x ) reads x, epsilon { pre { return x >= 0; } post { if(x == 0) { branch ZERO ("Zero argument"); return $this.Result == 0; } else { branch POS ("Positive argument"); return $this.Result >= 0 && Math.Abs( ($this.Result * $this. Result - x)/x) < epsilon; } } } } } Декларация
пространства имен Декларация класса Сигнатура операции Описание доступа
на чтение/запись Предусловие Постусловие Определение ветви
функциональности Ограничения
на результат Определение ветви
функциональности Ограничения
на результат
C
specification double SQRT ( double x ) reads x, epsilon { pre { return x >= 0.; } coverage BRANCHES { if(x == 0) return(ZERO, "Zero argument"); else return(POS, "Positive argument"); } post { if(coverage(BRANCHES)==ZERO) return SQRT == 0.; else return SQRT >= 0. && abs((SQRT*SQRT - x)/x) < epsilon; } } } Сигнатура операции Описание доступа
на чтение/запись Предусловие Описание
структуры тестового
покрытия Определение ветви
функциональности Определение ветви
функциональности Постусловие Ограничения
на результат Ограничения
на результат


В настоящее время промышленное производство


В настоящее время промышленное производство программного обеспечения (ПО) достигло таких масштабов и такой степени сложности, что необходимость в индустриально применимых технологиях систематического тестирования общепризнана. Особенно актуальным является создание таких технологий, которые обеспечивают одновременно качественное, система-тическое тестирование целевого ПО и высокую степень автоматизации разра-ботки тестов. Традиционные методы разработки тестов вручную уже не могут обеспечить качественное тестирование современных программных систем.
Обычно автоматизация тестирования сводится к автоматизации выполнения тестов и генерации отчетов по их результатам. Автоматизировать подготовку тестов и анализ полученных результатов труднее, поскольку при этом необходимо обращение к требованиям к ПО, соответствие которым, должно быть проверено во время тестирования. Требования же часто представлены в виде неформальных документов, а иногда - только как знания и опыт экспертов, аналитиков и проектировщиков ПО. Для того, чтобы вовлечь требования в автоматизированный процесс разработки тестов, необходимо перевести их в формальное представление, которое может быть обработано полностью автоматически. Для этой цели требования описывают в виде формальных спецификаций целевой системы, которые можно преобразовать в программы, выполняющие проверку соответствия работы целевого ПО зафиксированным в них требованиям.
Несмотря на активное развитие методов построения тестов на основе формальных спецификаций или формальных моделей в академическом сообществе, лишь немногие из них оказываются применимыми в индустрии производства ПО. Основная проблема здесь в том, что индустрии нужны не отдельные методы, а технологии, т.е. инструментально поддержанные системы методов для решения наборов связанных задач, относящихся к выделенному аспекту разработки ПО.
Данная статья представляет описание технологии UniTesK, которая была разработана в ИСП РАН на основе опыта нескольких проектов по верификации сложного промышленного ПО и нацелена на то, чтобы сделать возможным использование передовых методов тестирования в контексте индустриального производства ПО. UniTesK в первую очередь предназначена для разработки функциональных тестов на основе моделей требований к функциональности целевой системы. Проблемы построения тестов для проверки нефункцио-нальных требований выходят за рамки данной работы.
Структура статьи такова. Следующий за введением раздел содержит описание основных элементов технологии UniTesK, начиная с общего обзора ее базовых принципов и дальше раскрывая некоторые из них в деталях. В третьем разделе проводится сравнение UniTesK с другими подходами к разработке тестов на основе моделей. В четвертом разделе кратко описываются примеры приложений UniTesK и опыт использования этой технологии для тестирования промышленного ПО. В заключении рассматриваются направления дальней-шего развития этой технологии.

Выполнение тестов и анализ их результатов


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

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

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

Рис. 3. Описание найденной ошибки

Рис. 4. Отчет о тестовом покрытии.



Открытые проблемы и направления дальнейшего развития


Опыт разработки и использования UniTesK, как и работы других исследователей в области тестирования на основе моделей, показывает, что данное направление является весьма перспективным. Каковы же главные проблемы, которые мешают более широкому распространению тестирования на основе моделей? Их можно разделить на три основные группы:

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

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

Сейчас еще нет общего согласия по поводу нотаций и методов, при помощи которых ведется разработка моделей и тестов на их основе, нет унифицированной, общепринятой архитектуры тестирующей системы , отдельные инструменты для статического и динамического анализа программ и представления результатов анализа еще далеки от унификации. Тем не менее потребность в унификации уже назрела. Наиболее известным продвижением в области унификации является разработка документа UML Testing Profile [UML-TP], подготовленного в рамках программы MDA (Model Driven Architecture, [MDA]). Вместе с тем следует отметить, что авторы UML Testing Profile, возможно, пытаясь найти компромисс пригодный для всех участников консорциума, предлагают архитектуру, нацеленную больше на ручную разработку тестов.
Этот подход в некоторой степени может быть использован при разработке тестов на основе спецификаций сценариев использования, но он становится ограничивающим фактором, если в качестве модели целевого ПО берутся автоматные модели или спецификации ограничений, разработанные по методу Design-by-Contract. Следствием такого одностороннего подхода является непонимание потенциальных преимуществ использования спецификаций ограничений, и, в частности, языка OCL (Object Constraint Language), в промышленном программировании. Тем самым, проблема унификации представляется не только технической. Важно найти унифицированный подход, который позволил бы на базе единой концепции разрабатывать тесты на основе разных видов моделей с использованием ручных, автоматизированных и автоматических технологий.
Организационные проблемы на данный момент являются наиболее острыми [Robinson, Manage]. Как уже отмечалось выше, новая технология тестирования должна достаточно хорошо интегрироваться с имеющимися процессами разработки, и не требовать долгой и дорогой переподготовки персонала. Есть ли шанс найти для методов разработки тестов на основе моделей возможности сочетаться с традиционными методами разработки таким образом, что это позволит ввести новые технологии без ломки уже сложившихся процессов?
По-видимому, абсолютно безболезненным внедрение не будет, и причиной этого являются не столько технические проблемы, сколько проблемы персонала, причем как технического, так и управляющего. В настоящее время при промышленной разработке ПО широко используется подход к разработке тестов и тестированию как вспомогательной деятельности, не требующей навыков программирования, соответственно, в качестве тестировщиков используется, в основном, персонал без знания языков программирования и без базовых программистских умений. Пытаясь упростить проблемы организации взаимодействия команд разработчиков и тестировщиков, руководители проектов ориентируют тестировщиков только на системное тестирование, что влечет практическое отсутствие модульного и компонентного.


В этом случае появляется иллюзия, что тестировщики, имея большой запас времени, могут создать качественные тесты. В реальности же разработка обычно затягивается, и к моменту приемо-сдаточных испытаний система в состоянии продемонстрировать работоспособность на ограниченном количестве наиболее вероятных сценариев, но нуждается в серьезных доработках на большинстве нестандартных сценариев использования. Очевидно, что "сломать" негативные тенденции нельзя, они могут быть изжиты только вследствие эволюционных изменений. Сейчас такими эволюционными шагами могут стать дополнительные работы, которые поручаются проектировщикам и разработчикам. Эти дополнительные работы войдут в обиход реальных процессов разработки только тогда, когда их выполнение окажет положительный эффект на основную деятельность проектировщиков и программистов. Поэтому сейчас средства автоматизации тестирования на основе моделей имеет смысл вписывать в среду разработки, тем самым привлекая к тестированию не только профессиональных тестировщиков, но и разработчиков.
Для того чтобы расширить сообщество пользователей методов тестирования на основе моделей надо развивать формы обучения этим методам. Все инструменты UniTesK сопровождаются не только обычной пользовательской документацией, но и материалами для обучения. Предлагаются две формы обучения: традиционная университетская форма и форма интенсивного тренинга. Университетский курс требует от 15 до 30 часов занятий, тренинг требует 3-4 учебных дня по 8 академических часов каждый день. Материалы для университетов также как и лицензии на инструменты UniTesK для использования в образовательных целях предоставляются бесплатно. Также бесплатно предоставляются примеры спецификаций и тестов для разнообразных приложений. Основной стратегической целью дальнейших работ над UniTesK является построение полномасштабных индустриально применимых технологий тестирования на основе моделей для всех видов приложений, разрабатываемых в промышленности.
Для успешного развития технологий тестирования на основе моделей нужно одновременно поддерживать их эволюцию в трех направлениях: наращивать функциональность технологий, наращивать сопряженность этих технологий с современными процессами разработки и наращивать удобство их использования.


Особенно важно увеличивать удобство использования технологий для решения наиболее часто встречающихся задач.
Исследования по расширению области применимости подхода к тестированию на основе моделей должны проводиться по целому ряду направлений
Разработка полномасштабных технологий тестирования для всех компонентов таких видов приложений, как компиляторы, интерпретаторы, СУБД и др., функции которых связаны с обработкой запросов на хорошо структурированных формальных языках. Автоматизация тестирования приложений через графический пользовательский интерфейс. Разработка технологий полномасштабного тестирования распределенных систем, из которых наиболее широко встречаются сейчас многоуровневые приложению в архитектуре клиент-сервер приложений-сервер данных. Тестирование компонентов, имеющих очень сложную функциональность и очень ограниченный интерфейс: планировщики задач, сборщики мусора, менеджеры транзакций и пр. Тестированию приложений с элементами искусственного интеллекта: распознавание образов, выбор стратегии достижения цели в неопределенной ситуации, нечеткая логика, интеллектуальные агенты, и пр. Помимо решения задач собственно тестирования для привлечения внимания к технологиям тестирования на основе моделей необходимо искать подходящие метрики качества ПО, которые позволили бы продемонстрировать преимущества этого подхода. На данный момент многие метрики, используемые в промышленности для оценки качества ПО и состояния процесса тестирования, подходят для традиционной разработки тестов вручную, но приводят к парадоксам при попытке их использования в проектах, где тесты строятся автоматизировано на основе моделей. Кроме того, необходимо искать пути повышения прозрачности связей между используемыми моделями и требованиями к ПО, а также метрики переиспользуемости, позволяющие объективно оценить влияние изменений в требованиях к ПО, в требованиях к качеству тестирования, в архитектуре целевого ПО, в используемых технологиях разработки и пр. на изменения в тестах.Разработка и апробация таких метрик в промышленных проектах позволит повысить значимость технологий, нацеленных на повышение качества ПО, что, в свою очередь придаст новый импульс работам по автоматизации тестирования и по тестированию на основе моделей.

Аннотация. В статье рассматриваются


Грид (англ. grid ? решетка, сеть) ? это согласованная, открытая и стандартизованная компьютерная среда, которая обеспечивает гибкое, безопасное и скоординированное использование вычислительных ресурсов и данных. Термин “Грид” появился в начале 1990-х гг. в сборнике “TheGrid: Blueprint for a new computing infrastructure” под редакцией Яна Фостера как метафора о такой же легкости доступа к вычислительным ресурсам, как и к электрической сети (англ. power grid).

Создание Грид-систем было продиктовано необходимостью повышения вычислительных мощностей ресурсов. Так как требования к точности получаемых результатов и скорости работы вычислительных комплексов неуклонно растут, то возникает вопрос: как удовлетворить таким требованиям с наименьшими затратами? Один из возможных способов разрешения данной проблемы заключается в объединении различных ресурсов в одну систему. Причем необходимо, чтобы “объединенный” ресурс  работал как единое целое даже при отсутствии централизованного управления. Не должна также оказывать никакого отрицательного влияния на работоспособность системы и разнородность ресурсов, хотя особенности каждого из ресурсов также должны учитываться (для оптимизации времени выполнения).

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

Согласно Яну Фостеру, Грид-система (далее ГС) ? это система, которая: координирует использование ресурсов при отсутствии централизованного управления этими ресурсами; использует стандартные, открытые и универсальные протоколы и интерфейсы; нетривиальным образом обеспечивает высококачественное обслуживание.

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

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

Литература


Ian Foster The Grid: Blueprint for a New Computing Infrastructure. ? Morgan Kaufmann Publishers. ?  ISBN 1-55860-475-8 Ян Фостер. Пакет ИПО Грид UNICORE Пакет ИПО Грид gLite. http://glite.web.cern.ch/glite/ В.В. Галактионов, Н.А. Кутовский Тестирование GT4 в ОИЯИ.   Web Services Activity конрциума W3. A Message-Passing Interface Standard (MPI).  
А.В. Баранцев, И.Б. Бурдонов, А.В. Демаков, С.В. Зеленов, А.С. Косачев, В.В. Кулямин, В.А. Омельченко, Н.В. Пакулин, А.К. Петренко, А.В. Хорошилов. Труды Института системного программирования РАН, №5, 2004. Bertrand Meyer. Applying 'Design by Contract'. IEEE Computer, vol. 25, No. 10, October 1992, pp. 40-51. S. Schulze. Achieving Grid Interoperability: The ETSI Approach. The 20th Open Grid Forum - OGF20/EGEE 2nd User Forum. Manchester, UK. May 7 - 11, 2007 T.Rings, H.Neukirchen, J.Grabowski. Testing Grid ApplicationWorkflows Using TTCN-3. First International Conference on Software Testing, Verification, and Validation, ICST 2008, Lillehammer, Norway, April 9-11, 2008. E.Slabospitskaya, V.Petukhov, and G.Grosdidier. Glite I/O Storm Testing in EDG-LCG Framework. Nuclear Electronics and Computing 2005. Varna, Bulgaria, 12-18 September 2005. Lamch, D.; Wyrzykowski, R. Specification, Analysis and Testing of Grid Environments Using Abstract State Machines. International Symposium on Parallel Computing in Electrical Engineering, 2006. PAR ELEC 2006. 13-17 Sept. 2006 Pages:116 - 120


Обзор целевой системы


Объектом тестирования в данной работе является программный пакет GlobusToolkit 4.2. Ниже перечислены основные компоненты данного инструментария:

1) Компоненты поддержки времени выполнения (Common runtime components): C Core Utilities - обеспечение переносимости; C WS Core ? поддержка разработки Web-сервисов и выполнения клиентских приложений на C; Java WS Core ? поддержка разработки Web-сервисов и выполнения клиентских приложений на Java; CoG jglobus ? поддержка безопасности и выполнения не Web-сервисной части Java; Core WS Schema ? поддержка схемы стандартов WSRF и WSN; Python Core ? разработка и исполнение WS и не-WS клиентских приложений на языке Python; XIO ? расширяемые библиотеки ввода-вывода на С.

2) Управление данными (Data Management): GridFTP ? протокол передачи файлов; OGSA-DAI ? инфраструктура, основанная только на java-сервисах, для получения доступа к ресурсам и интеграции их в Грид; Reliable File Transfer ? технология надежной передачи файлов, основанная на Web-сервисах; Replica Location ? технология копирования и обнаружения данных; Data Replication ? технология идентификации групп файлов в среде Грид, и их локального копирования.

3) Управление выполнением (Execution Management): GRAM ? обнаружение местоположения, инициализация выполнения, наблюдение за работой и завершение удаленных задач на Грид-ресурсах; GridWay ? коллективное использование вычислительных ресурсов; MPICH-G2 ? реализация стандарта MPI .

4) Информационные сервисы (Information Services): MDS4 ? технология для слежения за ресурсами и их поиска, включающая сервисы индексирования и триггеры.

5) Компоненты безопасности (Security): C Security ? технология поддержки безопасности; CAS\SAML Utilities ? технология, относящиеся к авторизации сообществом; Delegation Service ? технология, предоставляющая хосту учетные данные; GSI-OpenSSH ? модифицированная версия OpenSSH, которая поддерживает аутентификацию сертификатов и их предоставление, удаленный зарегистрированный доступ и сервис передачи файлов; MyProxy ? технология хранения и извлечения учетных данных из репозитория.

Остановимся на некоторых принципиальных особенностях архитектуры Globus Toolkit 4.2.

Сервисно-ориентированная архитектура.
Globus Toolkit 4. 2 создан для поддержки приложений, в которых множества сервисов взаимодействуют посредством стандартных протоколов. ПО включает и сами сервисы полностью, и библиотеки, реализующие стандартные протоколы. Сервисы инфраструктуры. Globus Toolkit 4.2 включает встроенные сервисы для организации, наблюдения, управления и контроля доступа к таким элементам инфраструктуры, как ресурсы данных и вычислительные ресурсы. Web-сервисы. Globus Toolkit 4.2 использует протоколы стандартных Web-сервисов и механизмы описания сервисов, обнаружения, контроля доступа, аутентификации и авторизации. Контейнеры. ПО Globus Toolkit 4.2 включает компоненты, которые могут быть использованы для конструирования контейнеров для “помещения” в них Web-сервисов, написанных на Java, C, или Python. Безопасность. Подсистема безопасности выполняет задачи защиты сообщений, аутентификации, авторизации и передачи полномочий. Компоненты. Компоненты Globus Toolkit 4.2 не отвечают, вообще говоря, нуждам конечного пользователя напрямую: большинство из них выступает скорее как TCP\IP библиотека или реализация Web-сервера, чем как Web-браузер. Вместо этого,  Globus Toolkit 4.2 предоставляет широкий диапазон компонент и инструментов, которые обеспечивают высокоуровневые возможности, необходимые определенным сообществам пользователей. Согласно утверждению Globus Alliance, компонент Globus Toolkit 4.2 Java WS Core  реализует требования стандарта WSRF. В работе задача тестирования соответствия решалась именно для этого компонента. В рамках Java WS Core Web-сервис ? это просто Java-объект, а поддерживаемые им обмены сообщениями соответствуют методам класса. Для вызова методов класса следует посылать сервисам XML-сообщения по протоколу SOAP/HTTP. Стоит также заметить, что в реализации возможны передача сообщений как с применением шифрования, так и без него.

Опыт практического тестирования реализации ИПО Грид


Представленный выше метод к разработки тестовых наборов для ИПО Грид использовался при создании тестового набора для проверки соответствия реализаций ИПО Грид стандарту WSRF.

Применение технологии UniTESK для функционального тестирования инфаструктурного ПО Грид


,
Труды Института системного программирования РАН

Разработка формальной спецификации


Каждый обмен сообщениями в WSRF представляет собой пару <запрос ? ответ> где в качестве ответа может быть сообщение с возвращаемым значением или сообщение об ошибке. Тем самым обмены сообщениями WSRF можно представить как вызовы функций с возвращаемым значением, а сообщения об ошибках моделировать как исключения.

Благодаря этому в рассматриваемом методе формализации требований к ИПО Грид Web-сервис моделируется как объект некоторого класса, а обмены сообщениями между клиентом ИПО и реализацией представляются как вызовы методов объекта. Модельное состояние сервиса формализуется как набор полей объекта.

Такой способ моделирования неявно подразумевает синхронный сценарий взаимодействия между клиентом и сервисом: после отправки запроса клиент ожидает ответа. Не допускаются сценарии, в которых клиент может послать серию запросов, не дожидаясь ответов. Однако, анализ сценариев использования Грид-систем показал, что большинство современных клиентских приложений разрабатываются в синхронной парадигме. Более того, сам стандарт WSRF описывает семантику поведения сервиса в синхронном стиле. По этим причинам в рассматриваемом методе к формализации требований мы моделируем обмены сообщениями между клиентом и ИПО Грид как процедурные вызовы.

В модельное состояние ресурса необходимо включить переменные для представления свойств ресурса и окружения: EndpointReference ? модель идентификатора WS-ресурса, т.н. ссылка на конечную точку, удовлетворяющая требованиям стандарта WS-Addressing адресации Web-сервисов; ResourcePropertyDocument ? модель RPD WS-ресурса как множества элементов, моделирующие отдельные свойства (properties) ресурса; набор параметров модели, учитывающих отсутствие поддержки ряда необязательных обменов сообщениями в реализации; CurrentTime ? переменная, определяющая текущее системное время; TerminationTime ? переменная, определяющая время прекращения существования WS-ресурса.

Наличие первого поля определяется требованием спецификации WS-Resource об идентифицируемости.
Что же касается второго и третьего пунктов, то на них стоит остановиться поподробнее. Свойство ресурса как элемента RPD в спецификации моделируется классом со следующими полями: идентификатор-имя свойства (QName), значение свойства и минимальное количество его включений в RPD. Наличие последнего поля продиктовано рядом требований стандарта, касающихся тех свойств WS-ресурса, у которых оно является нулевым, т.е. наличие этого свойства, вообще говоря, необязательно. Что касается третьего пункта, то его наличие связано со спецификой организации стандарта WSRF 1.2. Дело в том, что требования стандарта, находящиеся даже в одной и той же его части, совершенно необязательно имеют один и тот же “ранг” в градации RFC 2119, т.е. ключевые слова в них различные. В Таблице 1 изображено распределение требований по частям стандарта в зависимости от их “ранга”:

WS-BaseFaults WS-Resource WS-Resource Properties WS-Resource Lifetime WS-ServiceGroup
MUST 17 6 115 30 41
SHOULD 1 0 12 8 15
MAY 11 6 32 13 17
Таблица 1. Распределение требований по отдельным частям стандарта WS-RF. Таким образом, в спецификации было формализовано около половины всех требований стандарта WSRF (порядка 160 требований), и порядка 60% содержащихся в частях WS-Resource, WS-ResourceLifetime и WS-ResourceProperties стандарта WSRF требований. Реализация остальных требований осуществлялась в медиаторе. Стоит также упомянуть о полях CurrentTime и TerminationTime класса WSResourceSpecification. Они используются для формализации требований “времени жизни” из спецификации WS-Resource, а также с требований спецификации WS-ResourceLifetime. Сигнатура метода, моделирующего отдельный обмен сообщений стандарта WSRF, определяется структурой сообщений запросов и ответов. Запросы представляются в виде набора параметров спецификационного метода, ответы представляются как возвращаемые значения метода, а сообщения об ошибках моделируются исключениями. Всё множество требований можно разделить на две основные группы: синтаксические и функциональные.


Синтаксические требования налагают ограничения на структуру сообщений и связи между полями одного сообщения. Функциональные требования представляют собой ограничения на функциональность обработки запросов и связь между содержимым запроса и ответом на запрос.
WS-BaseFaults WS-Resource WS-Resource Properties WS-Resource Lifetime WS-ServiceGroup
Синтаксис 27 1 50 12 5
Семантика 2 11 109 39 68
Таблица 2. Соотношение между синтаксическими и семантическими требованиями стандарта WS-RF. Функциональные требования к реализациям WSRF представляют собой описания простых операций, таких как изменение значения поля ресурса, добавление или удаление свойств (операции с множеством), детерминированных и полностью определенных. Такие требования в рамках предлагаемого метода моделируются в явном виде с использованием блоков update, поддерживаемых в реализации UniTESK ? инструменте JavaTESK. update-блок содержит инструкции, которые явным образом изменяют значения полей модельного состояния в соответствии с текстом требования стандарта. Синтаксические требования мы предлагаем проверять в медиаторах на этапе разбора сообщений, полученных от целевой системы.

Разработка медиатора


Основная функция медиатора, как компонента тестового набора, ? это установление соответствия между модельным объектом (объектом спецификационного класса) и целевой системой. В случае тестирования ИПО Грид возможность непосредственного доступа к полям и методам системы отсутствует, потому воздействовать на ГС можно было лишь посредством отправки соответствующих сообщений-запросов, а реакции принимать ? обрабатывая отклики. Соответственно, главной функцией медиатора является генерация сообщений-запросов и разбор сообщений-откликов с целью выявления полезной информации о выполнении операции.

В рассматриваемом методе медиаторы преобразуют параметры вызова спецификационного метода в XML сообщение, преобразуют в сообщение протокола SOAP/HTTP и отсылают его в целевую систему по установленному TCP соединению. Полученные ответы медиатор разбирает, проверяет соответствие ответа синтаксическим требованиям и формирует возвращаемое значение спецификационной функции.

Одна из особенностей разработки медиаторов для ИПО Грид заключается в том, что существующие реализации (в частности, GlobusToolkit 4.2) не удовлетворяют синтаксическим требованиям стандарта. Для проведения тестирования потребовалась адаптация медиаторов под нарушения стандарта, допускаемых реализацией. К примеру, Globus Toolkit 4.2 реализует один из последних предварительных проектов стандарта (draft) и поддерживает устаревшее пространство имен XML элементов (namespace); в результате реализация отвергала запросы, сформированные в соответствии со стандартом.

Также путем анализа исходного кода ИПО ГС Globus Toolkit 4.2, а также ряда экспериментов было выяснено, что реализацией не поддерживаются следующие обмены сообщениями ? PutResourceProperties, SetResourceProperties.

Разработка тестового сценария


Следующим этапом разработки тестового набора являлась разработка тестовых сценариев. Тестовым сценариям в технологии UniTESK отводится немаловажная роль. Как уже указывалось ранее, для их построения используется конечно-автоматная модель целевого ПО. При таком выборе модели актуальны ответы на следующие вопросы: Как вычислять состояния тестируемой системы? Как осуществляются переходы между состояниями? Как задается автомат теста и как производится обход графа переходов автомата?

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

В случае ИПО Грид в качестве объекта тестирования выступает WS-ресурс. Основной его характеристикой выступает, очевидно, RPD, как наиболее полно описывающая ресурс сущность. Следовательно, RPD может быть предъявлен в качестве описателя состояния WS-ресурса. Однако, такой подход является избыточным, а тестовые сценарии на его основе, вообще говоря, могут выполняться неопределенно долгое время. Действительно, представим себе, что WS-ресурс обладает n свойствами, каждое из которых может принимать только значение “1”, и  пусть изначально его RPD пуст. Рассмотрим конечный автомат, построенный на основе такого ресурса, причем в качестве модели состояния будем использовать его RPD, а в качестве переходов ? два метода: add и remove, обозначающие, соответственно добавление нового свойства и удаление некоторого старого. Тогда из начального состояния автомат сможет перейти в n состояний, соответственно, образуется 2n дуг на графе состояний. Из состояний “ранга 1” (т.е. таких, при которых RPD WS-ресурса содержит только одно свойство), которых ровно, в состояния “ранга 2” уже будет переходов. Из состояний “ранга 2” в состояния “ранга 3”, которых имеется  переходов уже будет при больших n. Это означает, что граф состояний будет иметь  вершин, а число ребер ? будет расти экспоненциально с ростом n, что приведет к крайне медленной работе обходчика а, следовательно, и замедлит работу тестов.
Другим важным недостатком такого подхода является его избыточность. Действительно, с точки зрения тестирования методов add и remove совершенно необязательно обходить все ребра такого графа (т.к. все свойства такого WS-ресурса с “точки зрения” данных методов эквивалентны). Достаточно обработать лишь некоторые (например, ребра, идущие из состояния, в котором все n свойств WS-ресурса равны 1 и ребра, идущие из начального состояния). Потому в ряде случаев представляется разумным выбирать другую модель состояния тестируемой системы. При разработке тестового сценария для тестирования соответствия ИПО Грид стандарту WSRF в качестве идентификатора состояния автомата теста мы предлагаем использовать мощность RPD WS-ресурса, т.е. количество свойств WS-ресурса. С одной стороны, такой способ существенно уменьшает размер предполагаемого графа состояний а, следовательно, и время работы тестов. С другой стороны, при таком задании состояния сохраняется детерминированность графа, что принципиально для корректной работы обходчика UniTESK. Ответ на второй вопрос традиционен для большинства приложений UniTESK ? переходы между состояниями автомата осуществляются посредством подачи стимулов в целевую систему. В качестве стимулов в случае построения тестового набора для ИПО Грид выступают, естественно, вызовы медиаторных методов. Последние же представляют собой не что иное, как отправки соответствующих XML-сообщений целевому ресурсу. Теперь перейдем к обсуждению третьего вопроса ? заданию автомата теста. Так как используется синхронная модель целевой системы, то для каждого спецификационного метода можно задать отдельный сценарный метод, который будет перебирать параметры метода и вызывать (неявно) медиатор для оказания тестового воздействия и оракул для проверки правильности возвращаемого значения.

Регламентирующие документы и требования к реализациям ИПО Грид


Как упоминалось во введении, в настоящее время при разработке ИПО Грид используются два семейства стандартов: OGSA и WSRF. Рассмотрим особенности формализации требований указанных стандартов.

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

По этим причинам стандарт OGSA не подходит в качестве основы для разработки формальных спецификации и основанного на них тестового набора.

Стандарт WSRF больше подходит для формализации. Стандарт содержит 5 спецификаций: WS-BaseFaults ? определяет формат сообщений об ошибках и механизм их обработки; WS-Resource ? определяет само понятие WS-Resource, форматы сообщений и семантику сервисов управления ресурсом; WS-ResourceLifetime ? определяет механизмы прекращения существования WS-Resource; WS-ResourceProperties - определяет, как WS-Resource связан с интерфейсом, описывающим Web-сервис, а также позволяет извлекать, изменять и уничтожать свойства WS-ресурса; WS-ServiceGroup ? определяет интерфейс к набору гетерогенных Web-сервисов.

Рассмотрим понятие ресурса (Resource) и WS-ресурса (WS-Resource), введенных в WS-Resource. Ресурс ? это логическая сущность, обладающая следующими характеристиками: идентифицируемость; наличие “времени жизни”; наличие множества (быть может пустого) свойств, представимых в XML InfoSet .

Теперь перейдем к понятию WS-ресурса. WS-ресурс представляет собой композицию ресурса и Web-сервиса, посредством вызова методов или полей которого осуществляется доступ к ресурсу. WS-ресурс также должен быть идентифицируемым (роль идентификатора должен играть XML элемент типа EndpointReference, описание которого содержится в стандарте WS-Addressing), а множество свойств ресурса, ассоциированного с сервисом, ? представимым в XML InfoSet.

Стандарт WSRF весьма удобен для анализа по причине его структурированности.
Так, например, большая их часть функциональных требований снабжена ключевыми словами стандарта RFC 2119 ? MUST, SHOULD, MAY. Кроме того, большинство требований снабжено блоками объяснений и примерами, написанными на псевдокоде, имеющем много общего с языком WSDL 2.0 описания Web-сервисов. Отдельные части стандарта имеют различные уровни обязательности в градации RFC 2119. А именно: WS-ресурс обязан (MUST) реализовывать требования спецификаций WS-Resource и WS-ResourceProperties, ему следует (SHOULD) руководствоваться требованиями WS-BaseFaults и он может (MAY) удовлетворять требованиям WS-ResourceLifetime. Следовательно, при создании тестового набора наиболее пристальное внимание нужно уделить именно первым двум обязательным спецификациям. Действительно, такой подход существенно упрощает как структуру тестового набора, так и его размер, при этом сохраняя корректность тестов как решения задачи соответствия. Итак, спецификация WS-Resource содержит определения ресурса и WS-ресурса. Также она содержит описания двух сообщений об ошибках, которые WS-ресурс может (MAY) возвращать в ответ на запросы. Что же касается спецификации WS-ResourceProperties, то в ней описан следующий способ хранения свойств WS-ресурса. Каждое свойство WS-ресурса представляет собой XML-элемент, полями которого являются уникальное имя свойства (в терминах спецификации WS-ResourceProperties ? QName), значение свойства и, возможно, служебные параметры. Все свойства ресурса объединены в некоторую композицию, называемую Resource Property Document (далее RPD), имеющую собственный идентификатор. Иными словами, свойства ресурса являются дочерними элементами по отношению к некоторому корневому элементу ? фактически, идентификатору RPD. Вместе с тем не указывается, каким именно образом сервис должен реализовывать свой RPD. В спецификации WS-ResourceProperties описаны следующие обмены сообщениями: GetResourcePropertyDocument ? получение всех свойств WS-ресурса; GetResourceProperty ? получение определенного свойства WS-ресурса; GetMultipleResourceProperties ? получение нескольких свойств WS-ресурса; QueryResourceProperties ? выяснение структуры свойств WS-Resource и выполнение запросов к RPD  и вычислений над его элементами (отдельно указывается диалект, на котором записано вычисляемое выражение, примером такого диалекта может служить язык XPath); PutResourcePropertyDocument ? замена всего RPD WS-ресурса “новым” RPD; SetResourceProperties ? изменение нескольких свойств WS-ресурса (фактически, некоторая композиция следующих трех обменов сообщениями); InsertResourceProperties ? добавление новых свойств WS-ресурса; UpdateResourceProperties ? изменение значений свойств WS-ресурса; DeleteResourceProperties ? удаление свойств WS-ресурса. В ходе анализа стандартов были выделены 325 функциональных требований, из них 29 относятся к спецификации WS-BaseFaults, 12 ? к WS-Resource, 51 ? к WS-ResourceLifetime, 159 ? к WS-ResourceProperties, 73 ? к WS-ServiceGroup.

Результаты тестирования


В данной работе была протестирована реализация ИПО ГС Globus Toolkit 4.0 средствами технологии UniTESK (JavaTESK). В качестве результатов тестирования выступали сгенерированные инструментом отчеты о покрытии требований. Всего было покрыто 60% функциональности, в чём данный тестовый набор не уступает тестам, применяемым разработчиками Globus Toolkit'а; последние для оценки качества тестирования измеряют покрытие тестами кода с помощью инструментов JUnit и Clover, и данные инструменты позволили разработчикам установить, что их юнит-тесты покрывают 60% функциональности компонента Java WS Core. Однако, как уже говорилось ранее, эти тесты ничего не могут сообщить о соответствии реализации Globus Toolkit 4.0 какому-либо стандарту. Таким образом, существующие и разработанные тесты не только дополняют друг друга, но и позволяют с разных точек зрения рассматривать реализацию.

В разработанный тестовый набор не вошли спецификации и тесты для необязательных требований спецификации WS-ServiceGroup и требования к операции QueryResourceProperties.

При тестировании реализации были выявлены несоответствия семантическим требованиям стандарта WSRF 1.2 в обменах сообщениями InsertResourceProperties и UpdateResourceProperties. В частности, эти методы позволяют добавлять или изменять значения свойств WS-ресурса с разными идентификаторами (QName), что запрещается требованиями стандарта.

Стандартизация Грид


Реализации ГС начали появляться с 1995 года, когда появился инфраструктурный программный пакет Globus Toolkit, ныне являющийся де-факто стандартом ГС. Он был выпущен организацией Globus Alliance ?  крупнейшим международным консорциумом в области Грид. В 1997 году был начат европейский проект по созданию программного пакета для ГС, приведший к созданию ИПО UNICORE. В 2004 году под эгидой проекта EGEE (Enabling Grids for E-sciencE) был выпущен пакет gLite. С появлением большого числа несовместимых между собой реализаций ИПО Грид необходимость унификации и стандартизации стала актуальной, и началась активная работа над созданием стандартов Грид. В 2004 году компания OASIS объявила о выходе стандарта WSRF (Web Services Resource Framework), а в 2005 году Global Grid Forum ? о стандарте OGSA (Open Grid Services Architecture). В том же 2005 году компания Microsoft выпустила ещё один стандарт, определяющий управление разнородными ресурсами ? WS-Management.

Таким образом в настоящее время действуют три группы стандартов для ИПО Грид.

Стандарты OGSA и WSRF. Ограничение области определения задачи


Рассмотрим характерные особенности стандартов, использующихся при разработке ИПО Грид: OGSA и WSRF.

Стандарт OGSA описывает инфраструктурное ПО (далее ИПО) OGSI (OpenGrid Services Infrastructure), занимающее “промежуточное” положение между приложениями пользователей и непосредственно вычислительными ресурсами. Это означает, что приложения не могут взаимодействовать с ресурсами напрямую, а только с ИПО. Таким образом, от пользователей скрывается внутренняя структура ГС, и им совершенно нет нужды вникать в детали реализации вычислений на самих ресурсах, приложение взаимодействует только с этой промежуточной средой. В основе архитектуры OGSI лежит понятие Грид-сервиса, который представляет собой механизм удаленных вызовов, разработанный специально для Globus Toolkit версии 3. Посредством удаленного доступа к методам Грид-сервиса приложение получает определенный вид обслуживания. Таким образом, унифицируются различные функции: доступа к вычислительным ресурсам, ресурсам хранения, базам данных и к любой программной обработке данных.

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

Одновременно с разработкой стандарта OGSA, в 2004 году консорциум OASIS предложил стандарт WSRF. Он также описывает некоторое ИПО, в основе которого, однако, лежат уже не Грид- а Web-сервисы. А в  2005 году был опубликован стандарт WS-Management, фактически, представляющий собой протокол для управления серверами, устройствами, и приложениями, основанный на использовании всё тех же Web-сервисов.

В последней версии Globus Toolkit разработчики отказались от использования Грид-сервисов в пользу Web-сервисов. За основу была взята спецификация WSRF. Соответственно, областью определения данной работы является именно ИПО, основанное на Web-сервисах, так как на этой концепции базируются наиболее широко используемые реализации ИПО Грид.

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

Существующие методы и подходы тестирования ИПО Грид


В 2006-м году Европейский институт стандартизации телекоммуникаций (ETSI) организовал экспертную группу по разработке тестового набора для тестирования совместимости ИПО Грид .

Метод, разрабатываемый в ETSI, основывается на разработке большого числа тестов (testcases) на языке TTCN-3. Каждый тест предназначен для проверки отдельной цели тестирования ? тестовой ситуации, сформулированной полуформально на языке TPL (Test Purpose Language). В настоящее время ведется выделение целей тестирования.

Прототип тестового набора для ИПО Грид на языке TTCN3 представлен в работе . Тестовый набор не связан с каким-либо стандартом для ИПО Грид. Вместо проверки требований стандарта тестовый набор проверяет применимость Грид в типовых сценариях использования ? постановки вычислительной задачи в очередь, выполнение задачи на одном из вычислительных узлов, доставка результатов вычисления клиенту.

В рамках проекта построения распределенной системы EGEE обработки экспериментальных данных с Большого адронного коллайдера проводилось тестирование пакета gLite, разработанного в CERN. В качестве основного метода тестирования используется интеграционное тестирование ? выполнение задач по пересылке крупных массивов данных. В случае тестирования gLite этот метод тестирования оправдан, так как основное назначение EGEE ? быстрая передача больших объемов данных с датчиков коллайдера в вычислительные системы. Задачу обеспечения совместимости с другими ИПО Грид разработчики EGEE не ставят.

Подход к тестированию ИПО Грид, близкий к представленному в данной статье, развивается в работе . Авторы предлагают использовать формализм автоматов с абстрактным состоянием (Abstract State Machine, ASM) и автоматически генерировать тестовые последовательности из обхода автомата модели. Вопросы анализа стандартов ИПО Грид, выделения требований и построения формальной модели требований не рассматриваются.

Технология автоматизированного тестирования UniTESK


С 1994 года в ИСП РАН разрабатывается технология автоматизированного тестирования UniTESK, которая с успехом использовалась для тестирования различных классов программных систем ? программных интерфейсов, телекоммункационных протоколов, аппаратного обеспечения. Доступ к ИПО Грид реализуется посредством различных механизмов удаленных вызовов процедур и служебных протоколов, что близко к области применимости UniTESK, поэтому данная технология была выбрана в качестве технологической платформы для разработки тестов.

Мы не будем здесь подробно описывать данную технологию, а остановимся лишь на основных этапах разработки тестов с её применением. Разработка тестов с применением технологии UniTESK ведется в следующие 7 этапов: анализ требований и их формализация, построение формальных спецификаций; формулировка требований к качеству тестирования; разработка тестовых сценариев, реализующих заданное покрытие; привязка тестовых сценариев к конкретной целевой системе посредством разработки медиаторов; получение готового тестового набора (трансляция и компиляция тестов); отладка и исполнение тестов; анализ результатов тестирования.

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

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



Тестирование реализации


Разработанный с помощью инструмента JavaTESK тестовый сценарий включает сценарии для семи методов (они же сценарные методы): GetResourcePropertyDocument, GetResourceProperty, GetMultipleResourceProperties Insert-, Update-  и DeleteResourceProperties, а также ImmediateDestroy.  Сценарий для GetResourceProperty предельно прост: в нём устанавливаются нижний и верхний пределы мощности RPD WS-ресурса, и пока мощность находится в заданном диапазоне, выбирается один из элементов RPD, т.е. некоторое свойство WS-ресурса. Имя свойства выбирается не произвольно, а как поле элемента массива, в который конвертируется RPD. Осуществляется это посредством применения метода toArray() библиотеки java.util.Set. Запрос искомого свойства осуществляется с помощью вызова одноименного медиаторного метода. Аналогичны сценарии для методов GetResourcePropertyDocument и GetMultipleResourceProperties.

Сценарий для InsertResourceProperties тоже несложен: в нём устанавливается только верхний предел мощности RPD WS-ресурса (нижний устанавливать бессмысленно, т.к. новое свойство может быть добавлено даже в RPD мощности 0), а затем с помощью одноименного медиаторного метода отправляется искомое XML-сообщение. В данном сценарии случайным образом генерируется имя свойства и его значение (с помощью функций класса java.util.Random). В некотором смысле аналогичен ему сценарий для метода UpdateResourceProperties ? также устанавливается верхний предел мощности RPD WS-ресурса, но вместе с ним устанавливается и нижний предел (т.к. невозможно изменить значение свойства у WS-ресурса, который не обладает ни одним свойством). Далее с помощью одноименного медиаторного метода отправляется XML-сообщение. Новое значение свойства также генерируется случайно.

Наконец, сценарий для обмена сообщениями DeleteResourceProperties таков: устанавливается нижний предел мощности RPD WS-ресурса, а затем вызывается одноименный медиаторный метод. Как и в сценарии для обмена GetResourceProperty, имя удаляемого свойства WS-ресурса не произвольно, а является именем элемента массива, в который конвертируется RPD  с помощью метода toArray() библиотеки java.util.Set.

Соответствующий граф состояний тестируемой системы имеет следующий вид(Рис.1):


Рис. 1 Граф состояний тестируемой системы Дуги, соответствующие переходам, приводящим к увеличению номера состояния, соответствуют вызовам сценарного метода InsertResourceProperties, обратные ? DeleteResourceProperties, а циклические ? вызовам методов GetResourcePropertyDocument, GetResourceProperty, GetMultipleResourceProperties. Стоит пояснить, почему именно 7 вышеуказанных обменов сообщениями были выбраны в качестве основных для написания соответствующего генератора XML-сообщений. В процессе разработки тестового набора предполагалось, что с его помощью будут протестированы сервисы контейнера  компонента Java WS Core инструментария Globus Toolkit 4.0. По умолчанию, всего в контейнере содержится 34 Web-сервисов, из которых 23 поддерживают некоторые обмены сообщениями из разделов WS-ResourceProperties и WS-ResourceLifetime стандарта WSRF. В частности, все они поддерживают обмен типа GetResourceProperty, 9 ? ImmediateDestroy а также Insert-, Update- и DeleteResourceProperties, 14 ? QueryResourceProperties, 13 ? GetMultipleResourceProperties, и 7 ? SetTerminationTime (обмен сообщениями из раздела WS-ResourceLifetime стандарта WSRF, соответствующий установке времени окончания работы WS-ресурса).  Соответственно, данные 7 обменов сообщениями являлись как достаточно простыми в смысле написания спецификационных методов (чего нельзя сказать, к примеру, об обмене QueryResourceProperties), так и позволяли в полной мере провести тестирование соответствия стандарту WSRF 1.2. Отдельный сценарий был реализован для метода ImmediateDestroy. В этом сценарии просто вызывается соответствующий медиаторный метод. Соответствующий граф состояний таков(Рис.2):

Рис 2. Граф состояний для сценария ImmediateDestroy Переход здесь всего 1, результатом выполнения сценарного метода является уничтожение WS-ресурса (состояние “Destroyed”).

Вопросы тестирования реализаций Грид


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

Также стоит отметить, что в предметной области имеет место специфичность средств взаимодействия пользовательских приложений и самой ГС ? в данном случае это Грид- и Web-сервисы, а также удаленные вызовы процедур. Web-сервис ? это программная система, идентифицируемая строкой URI (Uniform Resource Identifier ? некоторая последовательность, однозначно определяющая физический или абстрактный ресурс), чьи общедоступные интерфейсы определены на языке XML (eXtensible Markup Language ? расширяемый язык разметки, предоставляющий возможность хранения структурированных данных для обмена ими между программами). Описание этой программной системы может быть найдено другими программными системами, причем последние могут с ней взаимодействовать, обмениваясь сообщениями в формате XML с помощью протоколов Интернета (например, SOAP) .

Наиболее распространенными подходами к тестированию ГС являются следующие: Модульное тестирование (Unit testing)  - тестирование различных модулей исходного кода ПО. При таком подходе тесты пишутся для каждой нетривиальной функции или метода в отдельности. В частности, разработчики ИПО Globus toolkit широко используют JUnit для проверки реализации. Интеграционное тестирование (Integration testing, оно же тестирование взаимодействия) -  тестирование выполнения приложений на сборке ИПО Грид. Типичными примерами интеграционных тестовых сценариев являются пересылки больших массивов данных и проведение типовых расчетов.

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

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

В данной работе решалась задача


В данной работе решалась задача тестирования соответствия реализации ИПО ГС Globus Toolkit 4.2 стандарту систем управления распределенными ресурсами WSRF 1.2. Данный стандарт был проанализирован и на его основе составлен его каталог требований. Также была исследована структура и интерфейсы компонента Java WS Core программного пакета Globus Toolkit 4.2. На основе полученных данных был разработан тестовый набор для указанного программного пакета с применением технологии тестирования UniTESK (JavaTESK)  и проведено тестирование. Тестирование показало, что реализация Globus Toolkit 4.2  соответствует стандарту WSRF, хотя выявило отсутствие выполнения ряда необязательных требований, как семантических, так и синтаксических. Также тестирование показало, что технология UniTESK применима для тестирования ИПО ГС, в частности, имеют место следующие особенности её применения: Обмены сообщениями с Web-сервисами естественным образом моделируются спецификационными функциями; Для разработки тестового набора нужна библиотека классов для автоматизации построения различных (в том числе некорректных) сообщений Web-сервисов. В рамках данной работы были получены следующие результаты: показана применимость технологии UniTESK для разработки тестовых наборов для инфраструктурного программного обеспечения (ИПО, middleware) Грид-систем; разработан метод формализации требований и разработки тестов для стандартов ИПО Грид, основанных на архитектуре Web-сервисов; разработан прототип тестового набора для проверки соответствия реализаций ИПО Грид базовому стандарту WSRF версии 1.2: проведен анализ базового стандарта WSRF, составлен каталог требований; на основе каталога требований разработана формальная спецификация; проведено исследование реализации, на основе которого разработан медиатор разработан тестовый набор для реализации ИПО ГС Globus Toolkit 4.0 средствами технологии UniTESK (JavaTESK); проведено тестирование реализации ИПО ГС Globus Toolkit 4.0. при тестировании реализации был обнаружен ряд несоответствий базовому стандарту WSRF. В качестве направлений для дальнейшей работы мы рассматриваем разработку тестового набора, проверяющего специфические требования к сервисам ИПО Грид, такие как сервис передачи больших массивов данных, сервис создания и управления вычислительными задачами и др.