komponentnaq arhitektura sredy dlq testirowaniq na osnowe...

22
ПРОГРАММИРОВАНИЕ, 2010, N o 5, с. 5475 ТЕСТИРОВАНИЕ, ВЕРИФИКАЦИЯ И ВАЛИДАЦИЯ ПРОГРАММ УДК 681.3.06 КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ c 2010 г. В. В. Кулямин Институт системного программирования РАН 109004 Москва, ул. Солженицына, 25 E-mail: [email protected] Поступила в редакцию 21.01.2010 г. В статье представлен подход к построению архитектуры инструментария для тестирования на основе моделей, использующего современные компонентные технологии. Одна из основных идей, лежащих в его основе применение техник неинвазивной композиции, позволяющих с минимальны- ми затратами интегрировать множество независимо разработанных компонентов в сложную систе- му и переконфигурировать ее, не изменяя кода компонентов. Представленный подход является одним из первых применений компонентных технологий для проектирования тестовых систем. Также опи- сывается прототипная реализация предложенного подхода на базе свободно доступных библиотек и пример ее использования для построения тестов. 1. ВВЕДЕНИЕ Рост количества и разнообразия задач, возла- гаемых в современном мире на вычислительные системы, приводит к постоянному их усложне- нию и увеличению сложности всех видов дея- тельности, связанных с их построением и соп- ровождением. На решение проблем, связанных с этим ростом сложности, нацелены активно раз- вивающиеся в последние десятилетия компо- нентные технологии [1, 2] построения вычисли- тельных систем. При их применении системы выстраиваются из независимых компонентов, каждый из кото- рых решает узкий набор задач и взаимодейству- ет с окружением только через четко определен- ный интерфейс, т.е. является модулем. Помимо этого, программные компонентные технологии облегчают интеграцию компонентов, автомати- чески выполняя связывание и запуск компонен- тов (часто на лету, без прерывания работы сис- темы), помещенных в бинарном виде в рамки не- которой технологической инфраструктуры (ком- понентной среды). В результате компоненты мо- гут создаваться и поддерживаться независимы- ми разработчиками, что снижает расходы на разработку и сопровождение сложных систем. Компонентные технологии позволили значи- тельно повысить сложность создаваемых сис- тем, однако их развитие не сопровождается соот- ветствующим прогрессом в технологиях контро- ля качества программного обеспечения (ПО). В связи с этим проблемы обеспечения качества компонентных систем, включающие проверку корректности их работы, лишь усугубляются с возрастанием сложности и ответственности ре- шаемых ими задач. Источником таких проблем служит чрезвы- чайно высокая трудоемкость проверки коррект- ности систем при нелинейно зависящем от числа компонентов количестве возможных сценариев их взаимодействия и неявных зависимостей меж- ду ними. В свою очередь, эти трудности имеют следующие причины. Сложившаяся практика неполного и неточного описания интерфейсов ком- понентов приводит к возникновению мно- жества неявных зависимостей между ними. Согласно Парнасу [3], одному из основопо- ложников модульного подхода, полный ин- терфейс модуля должен задавать не только его синтаксическую структуру (имена опе- раций, типы их параметров и результатов), 54

Upload: others

Post on 02-Nov-2019

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

ПРОГРАММИРОВАНИЕ, 2010, No 5, с. 54–75

ТЕСТИРОВАНИЕ, ВЕРИФИКАЦИЯ И ВАЛИДАЦИЯ ПРОГРАММ

УДК 681.3.06

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ

ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ

c© 2010 г. В. В. КуляминИнститут системного программирования РАН

109004 Москва, ул. Солженицына, 25E-mail: [email protected]

Поступила в редакцию 21.01.2010 г.

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

основе моделей, использующего современные компонентные технологии. Одна из основных идей,

лежащих в его основе – применение техник неинвазивной композиции, позволяющих с минимальны-

ми затратами интегрировать множество независимо разработанных компонентов в сложную систе-

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

из первых применений компонентных технологий для проектирования тестовых систем. Также опи-

сывается прототипная реализация предложенного подхода на базе свободно доступных библиотек

и пример ее использования для построения тестов.

1. ВВЕДЕНИЕ

Рост количества и разнообразия задач, возла-гаемых в современном мире на вычислительные

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

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

разработку и сопровождение сложных систем.

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

компонентных систем, включающие проверку

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

Источником таких проблем служит чрезвы-чайно высокая трудоемкость проверки коррект-ности систем при нелинейно зависящем от числа

компонентов количестве возможных сценариев

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

• Сложившаяся практика неполного и

неточного описания интерфейсов ком-понентов приводит к возникновению мно-жества неявных зависимостей между ними.Согласно Парнасу [3], одному из основопо-ложников модульного подхода, полный ин-терфейс модуля должен задавать не только

его синтаксическую структуру (имена опе-раций, типы их параметров и результатов),

54

Page 2: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 55

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

высокие риски.Однако “менее рискованных”интерфейсов, смысл которых обычно не опи-сывается совсем, гораздо больше, и суммар-ные расходы, связанные с ошибками в ихработе, весьма значительны [4].

• Трудности интеграции средств вери-фикации в процессы разработки ПО.Такие средства по большей части являются

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

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

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

свое включение в разные технологические

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

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

приемлемую стоимость, в ее ходе создаетсямного вспомогательных артефактов, а ис-

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

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

компонентного ПО.

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

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

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

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

более аккуратного контроля их интеграции и

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

зования для решения разных задач во многом

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

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

тической проверке корректности сложных сис-тем является тестирование на основе моделей,сочетающее строгость формальных методов и

аккуратность выявления ошибок с гибкостью и

практичностью обычного тестирования.В данной работе представлены некоторые эле-

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

моделей и базирующейся на технологиях плат-формы Java, однако представляемая технология

ПРОГРАММИРОВАНИЕ No 5 2010

Page 3: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

56 КУЛЯМИН

пока находится в процессе создания. Основнаяже часть статьи посвящена ее архитектурному

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

компонентная архитектура предлагается впер-вые, хотя ряд ее элементов заимствованы из

наиболее передовых инструментов модульного

тестирования.Во втором разделе статьи рассматривается

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

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

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

2. ТЕСТИРОВАНИЕ

НА ОСНОВЕ МОДЕЛЕЙ

И ИНСТРУМЕНТЫ ТЕСТИРОВАНИЯ

Тестирование на основе моделей (model basedtesting) [7, 8] представляет собой подход к тес-тированию, в рамках которого тесты строятся

вручную, автоматизированным образом или ге-нерируются полностью автоматически на основе

модели поведения тестируемой системы и моде-ли ситуаций, связанных с ее работой.

• Модель поведения (behavior model) форма-лизует требования к тестируемой системе,т.е. описывает, какие внешние воздействияна нее в каких ситуациях допустимы, и какона должна реагировать на эти воздействия.

Модель поведения служит основой для тес-тового оракула [9–11] – компонента, произ-водящего оценку поведения системы во вре-мя тестирования.

Чаще всего при тестировании используются

модели в виде автоматов разного вида: ко-нечные или расширенные автоматы, систе-мы переходов [7], Statecharts [12, 13], вре-менные автоматы [14, 15] и т.д. Можно ис-пользовать другие разновидности моделей:контрактные спецификации в виде пред- и

постусловий операций, алгебраические спе-цификации в виде правил эквивалентности

различных цепочек вызовов операций, трас-совые модели, описывающие возможные це-почки воздействий и реакций системы.

• Модель ситуаций (situation model) форма-лизует структуру возможных тестовых си-туаций, составляющими которых являютсявнешние воздействия и состояния самой сис-темы и ее окружения, определяет различныеклассы ситуаций и их важность с точки

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

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

соответствует некоторому множеству таких

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

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

Модель ситуаций используется для реше-ния двух тесно связанных задач: опреде-ления критерия адекватности или полноты

тестирования [16] и определения числовыхметрик полноты тестирования. Если пол-нота тестирования определяется на основе

покрытия классов эквивалентных ситуаций

или элементарных событий, говорят о кри-терии тестового покрытия, метрике тес-тового покрытия, а достигнутый в ходе

тестирования процент покрытых классов на-зывают тестовым покрытием.

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

структурные элементы модели поведения, и за-тем строится (генерируется автоматически, соз-дается вручную или с помощью инструментов)

ПРОГРАММИРОВАНИЕ No 5 2010

Page 4: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 57

комплект тестов. Эти тесты проверяют соответ-ствие между реальным поведением тестируемой

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

Используемые для построения тестов методы

можно разделить на три типа.

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

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

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

• Комбинаторные методы строят тестовые

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

тестов, которые очень часто возникают в

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

достижение полноты тестов, вполне сопос-тавимы с нацеленными методами.Примеромслужат техники построения тестов на основе

автоматных моделей, создающие тесты в

виде набора путей по графу переходов ав-томата, минимизируя его с точки зрения

покрытия всех возможных состояний и пе-реходов.

2.1. Требования к представлениям моделейи инструментам тестирования

Инструменты тестирования на основе моделей

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

его использования эти представления должны

обладать следующими свойствами.

• Модели поведения:

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

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

в ходе построения моделей, посколькуэто позволяет выявить неточности, не-согласованность и неполноту в исход-ных формулировках и углубить их по-нимание [17].

◦ Средствами для явного указания связейс документами и стандартами, содер-жащими требования. Это позволяет

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

ПРОГРАММИРОВАНИЕ No 5 2010

Page 5: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

58 КУЛЯМИН

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

◦ Возможностью использования структу-ры моделей для задания моделей ситу-аций.

◦ Стоит поддерживать возможности ис-пользования таких моделей в рамках

других техник верификации (например,проверки моделей или статического ана-лиза).

◦ Полезна также возможность преобразо-вания модели поведения в однозначную

и полную документацию на моделиру-емую систему. Однако способы реали-зации этой возможности остаются за

рамками данной работы.

• Модели ситуаций:

◦ Средствами для описания ситуаций,связанных с различными аспектами по-ведения и структуры тестируемой сис-темы. Это относится к структуре вход-ных данных и результатов, состояниямсистемы, выполняемым инструкциям

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

◦ Средствами для явного указания связейопределяемых классов ситуаций с ис-ходными требованиями к системе.

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

◦ Возможностью автоматического извле-чения из кода тестируемой системы или

ее моделей, для нацеленного построениясоответствующих тестов.

Можно заметить, что требования к представ-лению моделей делятся на три типа: достаточнаядля практических целей выразительность, про-слеживаемость требований и возможность как

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

• Выполнение тестов. Без автоматизации вы-полнения тестов различных уровней невоз-можно организовать систематическое тес-тирование сложной системы.

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

тестов (оракулы), автоматически оцениваю-щие, правильно ли повела себя тестируемаясистема в каждом случае.

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

обращений и данных отдельных вызовов.

• Конфигурирование тестовых наборов. Тес-товый набор для сложной системы состоит

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

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

развития системы необходимо иметь гибкие

средства конфигурирования, позволяющие вкаждом конкретном случае достаточно легко

определить, какие тесты выполнять, а ка-кие нет, и соблюдающие ограничения на

взаимодействие между различными теста-ми.

2.2. Инструменты модульного тестирования

Рассмотрим теперь имеющиеся инструменты

тестирования с точки зрения их приближения к

инструментарию на основе компонентной техно-логии.

В большой степени обладают нужными свой-ствами средства модульного тестирования (unittesting) [5]. Наиболее известен из таких инстру-ментов JUnit [6], написанный на Java и предназ-наченный для тестирования кода на этом языке,

ПРОГРАММИРОВАНИЕ No 5 2010

Page 6: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 59

хотя исторически первым был SUnit [18, 19] дляпрограмм на Smalltalk.

Для этих инструментов характерны высокая

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

• Конфигурация тестов.

◦ Основные элементы тестов – тестовыеклассы и тестовые методы, описывае-мые как классы и методы языка Java,имеющие аннотацию @Test.

◦ Комплект тестов имеет иерархическуюструктуру: в нем выделяются тестовыенаборы (test suites), состоящие из тес-тов (tests). Далее в этом списке эти

термины используются только в спе-цифическом для TestNG смысле. Тес-ты и тестовые наборы определяются

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

◦ Методы инициализации (set-up) и фи-нализации (tear-down), используемыедля инициализации данных перед вы-полнением тестов и освобождения заня-тых ресурсов после, могут быть опреде-лены для всех элементов иерархии: длянаборов, тестов, классов и методов.

◦ Можно задавать зависимости между

тестовыми методами и группами, уп-равляющие порядком их выполнения и

отменяющие выполнение тестового ме-тода, если один из методов, от которыхон зависит, выполнился с ошибками.

• Тестовые данные и объекты.

◦ Тестовые методы в TestNG могут быть

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

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

работе теста.

◦ Можно создавать фабрики объектов,строящие разнообразные объекты тес-товых классов. Все входящие в тест ме-тоды выполняются для каждого такого

объекта.

• Проверка результатов тестирования.

◦ Выполняемые проверки, как и в другихинструментах модульного тестирова-ния, задаются с помощью вызовов ме-тодов-утверждений. Каждый такой ме-тод (их названия начинаются с assert)проверяет простое свойство своих аргу-ментов (равенство, неравенство null,вхождение объекта в коллекцию и пр.)и при его нарушении выдает в трассу

сообщение, также указываемое в видеаргумента.

◦ Дополнительно TestNG поддерживает

указание возможных исключений и ог-раничений на время работы тестового

метода в его аннотации.

Инструменты модульного тестирования актив-но используют независимые модули для реше-ния более специфичных задач. Например, dbUnit[22] – для организации работы с базами данных,httpUnit [23] – для обработки HTTP-запросов.Для более наглядной записи выполняемых в тес-тах проверок (близкой к формулировкам естест-венных языков) можно применять библиотеки,входящие в инструменты разработки на основе

функциональности (behavior driven development),например, JBehave [24] или NSpecify [25], дляорганизации тестовых заглушек – библиотеки

Mockito [26], EasyMock [27] и т.д.

2.3. Инструменты тестированияна основе моделей

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

архитектуре можно разделить на три группы.

ПРОГРАММИРОВАНИЕ No 5 2010

Page 7: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

60 КУЛЯМИН

• Традиционные “монолитные” инструменты,использующие специфические языки для

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

подходящих интерфейсов.

К инструментам такого типа относятся

практически все исследовательские средства

тестирования на основе моделей и ряд более

стабильных инструментов, использовавших-ся во многих разных проектах – TorX [28,29], TGV [30, 31], BZ-TT [32] иGotcha-TCBe-ans [33, 34]. Все они используют различныеавтоматные модели. На тех же принципахпостроены и коммерческие инструмен-ты Conformic Qtronic [35] и Smartesting TestDesigner (ранее Leirios) [36].

• “Монолитные” инструменты на основе рас-ширений широко используемых языков про-граммирования. Примеры – поддерживаю-щие технологию UniTESK [37–39] инстру-менты CTESK и JavaTESK, а также Spec-Explorer [40, 41], созданный вMicrosoft Rese-arch. В обоих случаях для моделирования

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

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

модульности. В частности, они достаточ-но легко интегрируются с компонентами от

независимых разработчиков и используются

в рамках более широкого инструментария.

Такие инструменты начали появляться не

так давно, около 4–5 лет назад. Два наиболееизвестных примера – это ModelJUnit [8, 42]и NModel [43, 44]. Похожий инструментmbt.tigris.org [45] использует для описания моде-лей графическую нотацию, поэтому гораздоменее приспособлен для использования в рам-ках чужих разработок. Иного рода пример –недавно созданная в Microsoft Research биб-лиотека для описания и контроля декла-

ративных ограничений на поведение .NET-компонентов CodeContracts [46, 47].

Возможности инструментов последнего вида,имеющих хорошую модульную структуру, стоитрассмотреть подробнее.

ModelJUnit и NModel построены как расшире-ния простых средств модульного тестирования.Модель ситуаций в них не задается, неявно кри-терии полноты закладываются в используемые

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

• Модель теста задается как расширенный ко-нечный автомат, представленный на языкепрограммирования (Java или C#) в видетестового класса, как и в средствах модуль-ного тестирования. Такой класс либо поме-чается с помощью аннотации (атрибута вC#), либо реализует некоторый интерфейс.Элементы автоматной модели – состояния,переходы, охранные условия переходов – за-даются с помощью методов и полей этого

класса.

◦ Состояние модели теста в NModel зада-ется набором значений полей тестово-го класса (можно определять поля, невключаемые в состояние), а в Model-JUnit – результатом метода getState().

◦ Действия, выполнение которых соот-ветствует переходам в модели теста,представляются методами, помеченны-ми определенной аннотацией (атрибу-том). В NModel действия могут бытьпараметризованными, причем набор

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

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

ПРОГРАММИРОВАНИЕ No 5 2010

Page 8: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 61

• NModel дополнительно имеет следующие воз-можности.

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

◦ Проверка моделей теста (model check-ing). Свойства безопасности соответст-вуют инвариантам, представленным

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

счет анализа достижимости состояний,в которых специально отмеченные ха-рактеристические методы возвращают

true.

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

• Ограничения записываются на языке C# в

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

• Можно описывать ограничения следующихвидов.

◦ Предусловия операций (метод Contract.Requires).

◦ Постусловия операций при нормальнойработе (Contract.Ensures).

◦ Постусловия операций при выдаче ис-ключения (Contract.EnsuresOnThrow).

◦ Утверждения о выполнении ограниче-ний в какой-то точке кода внутри ме-тода (Contract.Assert).

◦ Инварианты классов – помеченные осо-бым атрибутом методы, вызывающиеContract.Invariant.

• Помимо обычных выражений на C#, можноиспользовать следующие.

◦ Кванторные выражения в виде обраще-ний к Contract.Exists и Contract.ForAll.

◦ Обращение к значениям выражений довыполнения проверяемого метода в пост-условиях в виде вызова метода Contract.OldValue.

◦ Обращение к значению результата в

постусловиях с помощью Contract.Re-sult.

• Библиотека CodeContracts дополняется дву-мя инструментами: для статической про-верки сформулированных ограничений на

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

2.4. Итоги обзорасуществующих инструментов

Из приведенного обзора видно, что модуль-ные средства тестирования на основе моделей

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

тестирования. Необходимо дополнить имеющие-ся наработки следующими возможностями.

• Явное определение модели поведения

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

моделирования.Оно также дает возможностьстроить на основе одной модели поведения

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

• Расширенные выразительные возмож-ности для описания моделей поведения.В частности, нужно обеспечить возможностьиспользования разных стилей моделирова-ния и разнообразных техник построения тес-тов. Это требование является следствиемсложности и разнообразия требований к сов-ременному ПО [48, 49]. Библиотека CodeCon-tracts позволяет задавать только ограниче-ния на входные данные и результаты, что

ПРОГРАММИРОВАНИЕ No 5 2010

Page 9: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

62 КУЛЯМИН

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

• Явное определение моделей ситуаций

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

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

критерии полноты, учитывая покрытие какпроверяемого кода, так и требований к нему.

• Средства явной привязки моделей к

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

можно использовать текстовые сообщения

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

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

использование моделей в тестировании и дру-гих техниках верификации. NModel частичнорешает эту задачу для моделей тестов за

счет использования возможности расширять

определения классов новыми полями и мето-дами в C#.

3. АРХИТЕКТУРНЫЙ КАРКАС

ДЛЯ ТЕСТИРОВАНИЯ

НА ОСНОВЕ МОДЕЛЕЙ

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

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

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

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

эффективность в терминах трудозатрат на

описание некоторого набора элементов ин-терфейса [38, 50, 51].

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

оказываются расширенные автоматы и сис-темы переходов с возможностью их компо-зиции.

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

• Модели поведения и модели ситуаций, а так-же сами тесты и элементы инструментария

разработки предполагается оформлять в ви-де компонентов или наборов компонентов

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

Такой подход позволит применять для рабо-ты с этими моделями и для их интеграции

ПРОГРАММИРОВАНИЕ No 5 2010

Page 10: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 63

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

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

• Верификационные системы часто из-за болеемногочисленного ассортимента компонентов

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

внедрения зависимостей (dependency injec-tion) [52] и поддерживающих его библиотек-контейнеров.

3.1. Виды компонентов и их интеграция

Основой инструментария тестирования на ос-нове моделей предлагается сделать контейнервнедрения зависимостей (dependency injectioncontainer), позволяющий задавать список ком-понентов тестовой системы, инициализироватьих и определять связи между ними внешним

образом, без вмешательства в код этих компо-нентов.Верификационная система строится из компо-

нентов различных типов.

• Собственно, проверяемые компоненты.

Они должны поддерживать возможность

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

компонента.

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

• Модели поведения (обобщенные контракты).

Они оформляются на базовом языке про-граммирования как классы с несколькими

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

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

изменение состояния.

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

компонентов или, в случае различия интер-фейсов модели и компонента, – от адаптеров,устраняющих такие различия.

• Модели взаимодействия.При описании многокомпонентных систем

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

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

ПРОГРАММИРОВАНИЕ No 5 2010

Page 11: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

64 КУЛЯМИН

корректен любой набор событий, которыйможно линейно упорядочить так, чтобы каж-дое отдельное событие в таком порядке стало

корректным относительно моделей компо-нентов, создающих или обрабатывающих его[50].

Модели взаимодействия оформляются в виде

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

него компонентов.

• Модели ситуаций.

Модели ситуаций оформляются на базовом

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

Модели ситуаций зависят от проверяемых

компонентов, моделей поведения или теста,сообразно тому, в каких терминах они опи-сывают ситуации.

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

основе структуры кода или функциональ-ности часто используются при построении

тестов. Такие генерируемые компоненты да-лее будем называть вторичными.

• Тесты.

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

тест должен определять последовательность

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

◦ Для решения первой задачи можно ис-пользовать два подхода.

� На практике более часто применя-ется связка из автоматной модели

теста и генератора путей по графу

переходов автомата. Эта техникаположена в основу ModelJUnit и

NModel.В этом случае автоматная модель

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

поведения.

� Для ряда случаев более эффективно

применять монолитный генератор

последовательностей на базе инфор-мации о тестируемом интерфейсе.

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

� Первичные генераторы, которые

строят объекты некоторого типа.Такой генератор может быть ус-троен как итератор по некоторой

коллекции.

� Фильтры, выполняющие отсев дан-ных, не удовлетворяющих опреде-ленным ограничениям.

� Решатели ограничений, прямым об-разом строящие данные, удовлет-воряющие некоторым ограничени-ям.

� Комбинаторы, строящие данные

сложного типа из простых объектов.

� Преобразователи, генерирующие

данные некоторого типа по более

простому кодированному их пред-ставлению.

ПРОГРАММИРОВАНИЕ No 5 2010

Page 12: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 65

• Адаптеры.

Адаптеры устраняют возможные расхожде-ния между интерфейсами моделей и модели-руемых ими компонентов.

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

модели поведения.

Можно отметить, что во многих случаяхнебольшие расхождения между модельным

и проверяемым интерфейсами не требуют

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

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

• Заглушки (stubs, test doubles).

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

◦ Управляющая заглушка (mock) переда-ет в проверяемый компонент какие-тоданные в виде возвращаемых ее ме-тодами результатов и служит допол-нительным источником воздействий на

тестируемый компонент.

◦ Наблюдающая заглушка (test spy) фик-сирует вызовы ее операций и их аргу-менты для проверки корректности сде-ланных тестируемым компонентом об-ращений.

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

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

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

результаты очередного вызова ее операций.

• Вспомогательные компоненты. К вспомога-тельным относятся компоненты, решающиемногочисленные задачи организации работы

верификационной системы, интеграции ее

составляющих и сбора информации о про-исходящих событиях.

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

◦ Планировщики тестов, включающих

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

◦ Диспетчеры и синхронизаторы отдель-ных операций в асинхронных и парал-лельных тестах.

◦ Конфигураторы, определяющие связивнутри некоторых групп компонентов.

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

Конкретный набор компонентов и связи между

ними описываются в конфигурационном файле

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

5 ПРОГРАММИРОВАНИЕ No 5 2010

Page 13: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

66 КУЛЯМИН

Рис. 1. Схема построения тестовой системы.

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

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

3.2. Реализация предложенного подхода

Для реализации предложенной архитектуры в

качестве базового языка программирования был

выбран язык Java. Он обладает возможностями,необходимыми для описания различных ролей

классов и методов, а также связей между ком-понентами: средствами описания декларативнойинформации об элементах кода в виде аннотаций

и поддержкой получения в динамике информа-ции о структуре компонентов и сигнатурах их

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

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

Для описания моделей поведения была разрабо-тана небольшая библиотека, похожая, с однойстороны, на библиотеки проверки утвержденийв средствах модульного тестирования (использу-ются разнообразные методы assert()) и, с дру-гой стороны, на Microsoft CodeContracts (длядоступа к результату операции и пре-значениямвыражений используются методы result() и old-

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

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

ситуаций.

Тесты оформляются в стиле, аналогичномMo-delJUnit и NModel, но с некоторыми расширени-ями, частично заимствованными из TestNG.

• Поддерживается расширенная иерархия эле-ментов тестов: тестовые наборы, тесты, тес-товые классы, тестовые методы. Тестовыйнабор состоит из тестов, один тест можетвключать в себя несколько тестовых классов.

• Тестовый класс описывает расширенный ко-нечный автомат.

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

кода. Состояние теста является списком сос-тояний входящих в него классов.

• Тестовые методы определяют действия ав-томата, возможно, параметризованные. Зна-чения параметров извлекаются из связанного

ПРОГРАММИРОВАНИЕ No 5 2010

Page 14: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 67

с тестовым методом провайдера данных.Провайдер может быть генератором наборов

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

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

метода и его отдельных параметров.

• Действия могут иметь охранные условия,оформляемые в виде методов, возвращаю-щих булевский результат и зависящих от

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

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

только от текущего состояния).

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

Для построения заглушек используется сво-бодная библиотека Mockito [26]. Она имеет до-статочно богатые возможности для определения

управляющих и наблюдающих заглушек и ис-пользует интуитивно понятный синтаксис при

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

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

4. ПРИМЕР ПОСТРОЕНИЯ ТЕСТА

Далее описывается пример использования пред-

ложенных решений при построении тестов для

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

public interface Account

{

int getBalance();

int getMaxCredit();

Validator getValidator();

void setValidator(Validator p);

AuditLog getLog();

void setLog(AuditLog log);

int transfer(int sum);

}

Методы getBalance() и getMaxCredit() слу-жат для получения текущих значений баланса

и максимально возможного кредита. Баланс неможет быть отрицательным и превосходящим

максимально возможный кредит по абсолютной

величине.

Метод int transfer() осуществляет перевод

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

Данный счет позволяет использовать специа-лизированный валидатор транзакций, Validator,который опрашивается при любом переводе с

помощью предоставляемого им метода boolean

validateTransfer(Account a, int sum) и мо-жет разрешить или заблокировать перевод.

Еще одна функция счета – запись данных опопытках перевода денег в трассу для после-дующего аудита. При этом вызываются мето-ды интерфейса AuditLog: logKind(String s),logOldBalance(int b), logSum(int sum), log-

NewBalance(int b), записывающие, соответст-венно, итог транзакции (SUCCESS в случае ус-пешного перевода, BANNED в случае его блоки-ровки валидатором, IMPROPER в случае попыт-ки снятия слишком большой суммы), предшест-вующее значение баланса, переводимую сумму иновое значение баланса.

ПРОГРАММИРОВАНИЕ No 5 2010 5∗

Page 15: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

68 КУЛЯМИН

public class AccountContract{

int balance;int maxCredit;

Account checkedObject;

public void setCheckedObject(Account checkedObject){this.checkedObject = checkedObject;this.balance = checkedObject.getBalance();this.maxCredit = checkedObject.getMaxCredit();

}

public boolean possibleTransfer(int sum){if (balance + sum > maxCredit) return true;else return false;

}

public boolean transferPostcondition(int sum){boolean permission =

checkedObject.getValidator().validateTransfer(checkedObject, sum);

if (Contract.oldBooleanValue(possibleTransfer(sum)) && permission)return

Contract.assertEqualsInt(Contract.intResult(), sum, "Result should be equal to the argument")

&& Contract.assertEqualsInt(balance, Contract.oldIntValue(balance)+sum, "Balance should be increased on the argument")

&& Contract.assertEqualsInt(maxCredit, Contract.oldIntValue(maxCredit), "Max credit should not change");

elsereturn

Contract.assertEqualsInt(Contract.intResult(), 0, "Result should be 0")

&& Contract.assertEqualsInt(balance, Contract.oldIntValue(balance), "Balance should not change")

&& Contract.assertEqualsInt(maxCredit, Contract.oldIntValue(maxCredit), "Max credit should not change");

}

public void transferUpdate(int sum){if( possibleTransfer(sum)

&& checkedObject.getValidator().validateTransfer(checkedObject, sum))balance += sum;

}}

Рис. 2. Модель основной функциональности счета.

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

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

тояния.

Описание требований к работе с трассой для

аудита дано на рис. 3. Оно использует свободнораспространяемую библиотеку для организации

заглушек Mockito, вставляя заглушку для на-блюдения за сделанными вызовами между счетом

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

ПРОГРАММИРОВАНИЕ No 5 2010

Page 16: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 69

public class AccountLogSpy{

int balance;int maxCredit;

Account checkedObject;AuditLog logSpy;

public void setCheckedObject(Account checkedObject){this.checkedObject = checkedObject;this.balance = checkedObject.getBalance();this.maxCredit = checkedObject.getMaxCredit();logSpy = Mockito.spy(checkedObject.getLog());checkedObject.setLog(logSpy);

}

int oldBalance;boolean wasPossible;

public boolean possibleTransfer(int sum){if (balance + sum > maxCredit) return true;else return false;

}

public void initSpy(int sum){Mockito.reset(logSpy);oldBalance = balance;

}

public void transferLogSpy(int sum){boolean permission = checkedObject.getValidator().validateTransfer(checkedObject, sum);

if (wasPossible && permission){

Mockito.verify(logSpy).logKind("SUCCESS");Mockito.verify(logSpy).logNewBalance(balance);

}else if (!permission) Mockito.verify(logSpy).logKind("BANNED");else Mockito.verify(logSpy).logKind("IMPROPER");

Mockito.verify(logSpy).logOldBalance(oldBalance);Mockito.verify(logSpy).logSum(sum);

}

public void transferUpdate(int sum){if( possibleTransfer(sum)

&& checkedObject.getValidator().validateTransfer(checkedObject, sum)){

wasPossible = true;balance += sum;

}else

wasPossible = false;}

}

Рис. 3. Модель работы с трассой для аудита.

ПРОГРАММИРОВАНИЕ No 5 2010

Page 17: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

70 КУЛЯМИН

public class AccountCoverage extends AccountContract{

public void transferCoverage(int sum){boolean permission =

checkedObject.getValidator().validateTransfer(checkedObject, sum);

if (possibleTransfer(sum)) Coverage.addDescriptor("Possible transfer");else Coverage.addDescriptor("Too big sum");

if (permission) Coverage.addDescriptor("Permitted");else Coverage.addDescriptor("Not permitted");

if(balance == 0) Coverage.addDescriptor("Zero balance");else if(balance > 0) Coverage.addDescriptor("Positive balance");else Coverage.addDescriptor("Negative balance");

if(sum == 0) Coverage.addDescriptor("Zero sum");else if(sum > 0) Coverage.addDescriptor("Positive sum");else Coverage.addDescriptor("Negative sum");

}}

Рис. 4. Модель ситуаций.

@Test public class AccountTest{

Account account;boolean permission = true;

@Mock Validator validatorStub;

public AccountTest(){MockitoAnnotations.initMocks(this);Mockito.when(validatorStub.validateTransfer(Mockito.<Account>any()

, Mockito.anyInt())).thenReturn(true);}

public void setAccount(Account account){this.account = account;account.setValidator(validatorStub);

}

public Validator getPermitterStub() { return validatorStub; }

@State public int getBalance() { return account.getBalance(); }

@State public boolean getPermission() { return permission; }

@Test@DataProvider(name = "sumArray")@Guard(name = "bound")public void testDeposit(int x){account.transfer(x);

}

Рис. 5. Модель теста.

аргументами. Поскольку построенная заглушкаимеет модельное состояние, в ней также опре-делен метод-синхронизатор этого состояния. За-глушка должна инициализироваться после каж-

дого вызова transfer(), для этого в ней опреде-лен метод initSpy().

Описание модели ситуаций представлено на

рис. 4. В ней ситуации классифицируются по

ПРОГРАММИРОВАНИЕ No 5 2010

Page 18: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 71

@Test@DataProvider(name = "sumIterator")public void testWithdraw(int x){account.transfer(-x);

}

@Test@Guard(name = "bound")public void testIncrement(){account.transfer(1);

}

@Testpublic void switchPermission(){permission = !permission;Mockito.when(validatorStub.validateTransfer(Mockito.<Account>any()

, Mockito.anyInt())).thenReturn(permission);}

public boolean bound(){return getBalance() < 5 || !permission;

}

public int[] sumArray = new int[]{1, 2};

public Iterator<Integer> sumIterator(){return (Utils.ArrayToTypedList(sumArray)).iterator();

}}

Рис. 5 Модель теста (окончание).

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

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

и нуждается в синхронизаторе состояния, этамодель наследует модели функциональности, ис-пользуя повторно определенные в ней элементы

кода.

Модель теста для счета выглядит так, какпоказано на рис. 5.

Состояние теста состоит из двух элементов:текущего значения баланса и значения поля per-

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

по разным тестовым методам, хотя при этомвызывается один и тот же метод тестируемого

объекта. Всего имеется четыре тестовых мето-да, соответствующих действиям в описываемомавтомате.

• Метод testDeposit() проверяет помещениеденег на счет. Он параметризован, значенияпараметров при работе теста берутся из мас-сива sumArray.Кроме того, этот метод имеетохранное условие, позволяющее вызыватьего только в тех случаях, когда текущийбаланс не превосходит 5 и валидатор-заглуш-ка допускает выполнение операций.

• Метод testWithdraw() проверяет снятие де-нег со счета. Значения его параметра берут-ся из того же массива, но с использованиемметода-итератора.

• Метод testIncrement() проверяет добавле-ние на счет суммы, равной 1. Он имеет

то же самое охранное условие, что и методtestDeposit().

• Метод switchPermission() ничего не про-веряет, он только переключает текущее зна-чение поля permission, чтобы протестиро-вать работу счета с разными балансами и

ПРОГРАММИРОВАНИЕ No 5 2010

Page 19: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

72 КУЛЯМИН

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<bean id="accountImpl" class="mbtest.tests.AccountImpl"></bean>

<bean id="accountTest" class="mbtest.tests.AccountTest"><property name="account" ref="accountImpl"/>

</bean>

<bean id="accountContract" class="mbtest.tests.AccountContract"><property name="checkedObject" ref="accountImpl"/>

</bean>

<bean id="accountCoverage" class="mbtest.tests.AccountCoverage"><property name="checkedObject" ref="accountImpl"/>

</bean>

<bean id="accountLogSpy" class="mbtest.tests.AccountLogSpy"><property name="checkedObject" ref="accountImpl"/>

</bean>

<bean id="accountContractExecutor" class="mbtest.contracts.ContractExecutor"><property name="postcondition"

value="mbtest.tests.AccountContract.transferPostcondition"/><property name="updater" value="mbtest.tests.AccountContract.transferUpdate"/><property name="object" ref="accountContract"/>

</bean>

<bean id="accountCoverageExecutor" class="mbtest.coverage.CoverageExecutor"><property name="coverage"

value="mbtest.tests.AccountCoverage.transferCoverage"/><property name="updater" value="mbtest.tests.AccountCoverage.transferUpdate"/><property name="object" ref="accountCoverage"/>

</bean>

Рис. 6. Конфигурация тестовой системы.

разными результатами валидации переводов.

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

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

fer() с помощью поддерживаемой Spring техни-ки привязки аспектов.Приведенный пример демонстрирует неинва-

зивность использованного метода построения

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

основной функциональности и модель ситуаций

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

компонента, играющего две разные роли.

5. ЗАКЛЮЧЕНИЕ

В работе представлена компонентная архитек-тура инструментария для тестирования на осно-ве моделей, построенная на основе компонентныхтехнологий с использованием принципа неинва-зивной композиции. Впервые дается целостноепредставление такой архитектуры, хотя отдель-ные ее элементы уже использовались в инстру-ментах типа TestNG, ModelJUnit иNModel.Опи-сана реализация предложенного подхода на базе

ПРОГРАММИРОВАНИЕ No 5 2010

Page 20: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 73

<bean id="accountSpyExecutor" class="mbtest.contracts.SpyExecutor"><property name="initialization" value="mbtest.tests.AccountLogSpy.initSpy"/><property name="postcondition"

value="mbtest.tests.AccountLogSpy.transferLogSpy"/><property name="updater" value="mbtest.tests.AccountLogSpy.transferUpdate"/><property name="object" ref="accountLogSpy"/>

</bean>

<aop:config><aop:aspect id="accountContractAspect" ref="accountContractExecutor">

<aop:pointcut id="accoutTransfer"expression="execution(* mbtest.tests.Account.transfer(..))"/>

<aop:around pointcut-ref="accoutTransfer" method="execute"/></aop:aspect>

<aop:aspect id="accountCoverageAspect" ref="accountCoverageExecutor"><aop:pointcut id="accoutCTransfer"

expression="execution(* mbtest.tests.Account.transfer(..))"/><aop:around pointcut-ref="accoutCTransfer" method="execute"/>

</aop:aspect>

<aop:aspect id="accountSpyAspect" ref="accountSpyExecutor"><aop:pointcut id="accoutSTransfer"

expression="execution(* mbtest.tests.Account.transfer(..))"/><aop:around pointcut-ref="accoutSTransfer" method="execute"/>

</aop:aspect></aop:config>

</beans>

Рис. 6 Конфигурация тестовой системы (окончание).

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

Имеющаяся на настоящий момент реализация

описываемого подхода содержит следующие не-достатки, которые нужно устранить.

• Во-первых, нужно модифицировать стан-дартный контекст внедрения зависимостей

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

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

рамках элемента <aop:config> и определе-ния последних трех компонентов. Написаниеи понимание конфигурационных файлов зна-чительно упростятся, и такие файлы смогутстать полноценным инструментом конфигу-рирования и настройки сложных тестовых

наборов, не требующим их перекомпиляции.

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

из открытых библиотек для трансформации

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

стать сопоставимым с использованием для

этого ведущих специализированных инстру-ментов.

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

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

ПРОГРАММИРОВАНИЕ No 5 2010

Page 21: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

74 КУЛЯМИН

ники построения тестов.

Однако уже сейчас предложенная архитектура

демонстрирует свои основные достоинства

по сравнению с традиционными “монолитными”инструментами построения тестов – высокую

гибкость, возможность совместного использова-ния с разнообразными библиотеками, многочис-ленными инструментами, предназначенными дляработы с компонентами Java (средами разработ-ки, анализаторами кода, отладчиками и т.д.),возможность интеграции в более мощные среды.

СПИСОК ЛИТЕРАТУРЫ

1. Szyperski C. Component Software: Beyond Object-Oriented Programming. 2nd ed. Boston: Addison-Wesley Professional, 2002.

2. Heineman G.T., Councill W.T. Component-BasedSoftware Engineering: Putting the Pieces Together.Addison-Wesley Professional, 2001.

3. Parnas D. Information Distribution Aspects of De-sign Methodology. Proc. of 1971 IFIP Congress.North Holland, 1971.

4. Tassey G. (ed.) The Economic Impacts of Inad-equate Infrastructure for Software Testing. NISTReport. 2002.

5. Hamill P. Unit Test Frameworks. Tools for High-Quality Software Development. O’Reilly Media,2004.

6. http://www.junit.org.

7. Broy M., Jonsson B., Katoen J.-P., Leucker M.,Pretschner A. (eds.) Model-Based Testing of Reac-tive Systems. Advanced Lectures // LNCS. V. 3472.Springer-Verlag, 2005.

8. Utting M., Legeard B. Practical Model-Based Test-ing: A Tools Approach. Morgan-Kaufmann, 2007.

9. Peters D., Parnas D. Using Test Oracles Generat-ed from Program Documentation // IEEE Trans.on Software Engineering. 1998. V. 24. No 3. P. 161–173.

10. Hoffman D. Analysis of a Taxonomy for Test Ora-cles. Quality Week, 1998.

11. Baresi L., Young M. Test Oracles. Tech. ReportCIS-TR-01-02. http://www.cs.uoregon.edu/∼mich-al/pubs/oracles.html.

12. Harel D. Statecharts: A visual formalism for com-plex systems // Science of Computer Program-ming. June 1987. V. 8. No 3. P. 231–274.

13. Drusinsky D. Modeling and verification using UMLstatecharts. Elsevier, 2006.

14. Alur R., Dill D.L. A Theory of Timed Automata// Journal of Theoretical Computer Science. 1994.V. 126. No 2. P. 183–235.

15. Springintveld J., Vaandrager F., D’Argenio P.R.Testing Timed Automata // Theoretical ComputerScience. March 2001. V. 254. No 1–2. P. 225–257.

16. Zhu H., Hall P., May J. Software Unit Test Cov-erage and Adequacy // ACM Computing Surveys.December 1997. V. 29. No 4. P. 366–427.

17. Кулямин В.В., Пакулин Н.В., Петренко О.Л.,Сортов А.А., Хорошилов А.В. Формализациятребований на практике. Препринт No 13. ИСПРАН. Москва, 2006.

18. Beck K. Kent Beck’s Guide to Better Smalltalk:A Sorted Collection. Cambridge University Press,1998.

19. http://sunit.sourceforge.net/.

20. Beust C., Suleiman H. Next Generation Java Test-ing: TestNG and Advanced Concepts. Addison-Wesley Professional, 2007.

21. http://testng.org/.

22. http://www.dbunit.org.

23. http://www.httpunit.org.

24. http://jbehave.org/.

25. http://nspecify.sourceforge.net/.

26. http://mockito.org/.

27. http://easymock.org/.

28. Tretmans J., Brinksma E. TorX: Automated Mo-del-Based Testing. Proc. of the 1st European Con-ference on Model-Driven Software Engineering. Nu-remberg, Germany. December 2003. P. 31–43.

29. http: // fmt.cs.utwente.nl / tools / torx / introducti-on.html.

30. Fernandez J.-C., Jard C., Jeron T., Nedelka L.,Viho C. Using On-the-Fly Verification Techniquesfor the Generation of Test Suites. Proc. of the 8thInternational Conference on Computer-Aided Ver-ification // LNCS. V. 1102. P. 348–359. Springer,1996.

31. http://www.inrialpes.fr/vasy/cadp/man/tgv.html.

32. Ambert F., Bouquet F., Chemin S., Guenaud S.,Legeard B., Peureux F., Vacelet N., Utting M.Z-TT: A tool-set for test generation from Z andB using constraint logic programming. Proc. ofFormal Approaches to Testing of Software. Brno,Czech Republic. August 2002. P. 105–119.

ПРОГРАММИРОВАНИЕ No 5 2010

Page 22: komponentnaq arhitektura sredy dlq testirowaniq na osnowe ...panda.ispras.ru/~kuliamin/docs/ComMBT-2010-ru.pdfprogrammirowanie, 2010, No 5, S. 54{75 testirowanie, werifikaciq i walidaciq

КОМПОНЕНТНАЯ АРХИТЕКТУРА СРЕДЫ ДЛЯ ТЕСТИРОВАНИЯ НА ОСНОВЕ МОДЕЛЕЙ 75

33. Hartman A., Nagin K. TCBeans Software TestToolkit. Proc. of the 12th International SoftwareQuality Week. May 1999.

34. Farchi E., Hartman A., Pinter S.S. Using a model-based test generator to test for standard confor-mance // IBM Systems Journal. 2002. V. 41. No 1.P. 89–110.

35. http://www.conformiq.com/qtronic.php.

36. http://www.smartesting.com/index.php/cms/en/explore/products.

37. Bourdonov I., Kossatchev A., Kuliamin V., Pe-trenko A. UniTesK Test Suite Architecture. Proc.of FME 2002 // LNCS. V. 2391. P. 77–88. Springer,2002.

38. Кулямин В.В., Петренко А.К., Косачев А.С.,Бурдонов И.Б. Подход UniTesK к разработке

тестов // Программирование. 2003. No 6. P. 25–43.

39. http://www.unitesk.ru.

40. Campbell C., Grieskamp W., Nachmanson L., Schu-lte W., Tillmann N., Veanes M. Testing Concur-rent Object-Oriented Systems with Spec Explorer.Proc. of Formal Methods Europe // LNCS. V. 582.P. 542-547. Springer, 2005.

41. http://research.microsoft.com/en-us/projects/SpecExplorer/.

42. http://www.cs.waikato.ac.nz/∼marku/mbt/model-junit/.

43. Jacky J., Veanes M., Campbell C., Schulte W.Model-based Software Testing and Analysis withC#. Cambridge University Press, 2007.

44. http://nmodel.codeplex.com/.

45. http://mbt.tigris.org/.

46. Barnett M., Fahndrich M., de Halleux P., Logoz-zo F., Tillmann N. Exploiting the Synergy betweenAutomated-Test-Generation and Programming-by-Contract. Proc. of ICSE 2009. Vancouver, Canada.May 2009.

47. http://research.microsoft.com/en-us/projects/con-tracts/.

48. Kaner C., Bach J., Pettichord B. Lessons Learnedin Software Testing. John Wiley & Sons, 2002.

49. Кулямин В.В. Интеграция методов верифика-ции программных систем //Программирование.2009. No 4. P. 41–55.

50. Kuliamin V., Petrenko A., Pakoulin N. PracticalApproach to Specification and Conformance Test-ing of Distributed Network Applications. Proc. ofISAS’2005. Berlin, Germany. Malek M., Nett E.,Suri N. (eds.) Service Availability // LNCS. V. 3694.P. 68–83. Springer-Verlag, 2005.

51. Grinevich A., Khoroshilov A., Kuliamin V., Mar-kovtsev D., Petrenko A., Rubanov V. Formal Meth-ods in Industrial Software Standards Enforcement.Proc. of PSI’2006. Novosibirsk, Russia. 2006.

52. Fowler M. Inversion of Control Containers and theDependency Injection Pattern. 2004. http://www.martinfowler.com/articles/injection.html.

53. Johnson R., Hoeller J., Arendsen A., Risberg T.,Sampaleanu C. Professional Java Development withthe Spring Framework. Wrox, 2005.

54. http://www.springsource.org.

ПРОГРАММИРОВАНИЕ No 5 2010