Интеграционное тестирование
Интеграционное тестирование — это тестирование
части системы, состоящей из двух и более модулей.
Основная задача интеграционного тестирования — поиск
дефектов, связанных с ошибками в реализации и
интерпретации интерфейсного взаимодействия между
модулями.
С технологической точки зрения интеграционное
тестирование является количественным развитием
модульного, поскольку так же, как и модульное
тестирование, оперирует интерфейсами модулей и
подсистем и требует создания тестового окружения,
включая заглушки на месте отсутствующих модулей.
Основная разница между модульным и интеграционным
тестированием состоит в целях, то есть в типах
обнаруживаемых дефектов, которые, в свою очередь,
определяют стратегию выбора входных данных и методов
анализа.
Интеграционное тестирование применяется на этапе
сборки модульно оттестированных модулей в единый
комплекс. Известны два метода сборки модулей:
• Монолитный, характеризующийся одновременным объединением всех модулей в тестируемый комплекс.
• Инкрементальный, характеризующийся пошаговым (помодульным) наращиванием комплекса программ с пошаговым тестированием собираемого комплекса. В инкрементальном методе выделяют две стратегии добавления модулей:
— «Сверху вниз» и соответствующее ему восходящее
тестирование.
— «Снизу вверх» и соответственно нисходящее тестирование.
Особенности монолитного тестирования
Для замены неразработанных к моменту тестирования
модулей, кроме самого верхнего, необходимо
дополнительно разрабатывать драйверы и заглушки,
замещающие отсутствующие на момент сеанса
тестирования модули нижних уровней.
Сравнение монолитного и интегрального подход
Монолитное тестирование требует больших трудозатрат,
связанных с дополнительной разработкой драйверов и
заглушек и со сложностью идентификации ошибок,
проявляющихся в пространстве собранного кода.
Пошаговое тестирование связано с меньшей
трудоемкостью идентификации ошибок за счет
постепенного наращивания объема тестируемого кода и
соответственно локализации добавленной области
тестируемого кода.
Монолитное тестирование предоставляет большие
возможности распараллеливания работ, особенно на
начальной фазе тестирования.
Особенности нисходящего тестирования заключаются в следующем:
- организация среды для исполняемой очередности вызовов оттестированными модулями тестируемых модулей,
- постоянная разработка и использование заглушек,
- организация приоритетного тестирования модулей, содержащих операции обмена с окружением, или модулей, критичных для тестируемого алгоритма.
Недостатки нисходящего тестирования :
- Проблема разработки достаточно "интеллектуальных" заглушек, т.е. заглушек, пригодных к использованию при моделировании различных режимов работы комплекса, необходимых для тестирования;
- Сложность организации и разработки среды для реализации исполнения модулей в нужной последовательности
- Параллельная разработка модулей верхних и нижних уровней приводит к не всегда эффективной реализации модулей из-за подстройки (специализации) еще не тестированных модулей нижних уровней к уже оттестированным модулям верхних уровней
Особенности восходящего тестирования в организации
порядка сборки и перехода к тестированию модулей,
соответствующему порядку их реализации.
Недостатки восходящего тестирования :
- Запаздывание проверки концептуальных особенностей тестируемого комплекса
- Необходимость в разработке и использовании драйверов
Особенности интеграционного тестирования для объектно-ориентированного программирования
Разработка проекта при объектно–ориентированном
программировании строится по принципу - от определения
классов, используемых в программе, построения дерева
классов к реализации кода проекта.
Объектно-ориентированное программное
обеспечение является событийно управляемым.
Передача управления внутри программы осуществляется
не только путем явного указания последовательности
обращений одних функций программы к другим, но и путем
генерации сообщений различным объектам, разбора
сообщений соответствующим обработчиком и передача их
объектам, для которых данные сообщения предназначены.
Тестирование объектно-ориентированной программы
должно включать те же уровни, что и тестирование
процедурной программы - модульное, интеграционное и
системное. Внутри класса отдельно взятые методы
имеют императивный характер исполнения. Все
языки ООП возвращают контроль вызывающему объекту,
когда сообщение обработано. Поэтому каждый метод
( функция - член класса) должен пройти
традиционное модульное тестирование по выбранному
критерию C (как правило, С1 ).
Каждый класс должен быть рассмотрен как
субъект интеграционного тестирования .
Интеграция для всех методов класса проводится с использованием инкрементальной стратегии снизу вверх. При этом можно использовать тесты для классов-родителей тестируемого класса, что следует из принципа наследования - от базовых классов, не имеющих родителей, к самым верхним уровням классов.
Графовая модель класса объектно-ориентированной программы, на интеграционном уровне в качестве узлов использует методы. Дуги могут быть образованы двумя способами:
- прямым вызовом одного метода из кода другого, если вызываемый метод виден из класса, содержащего вызывающий метод. Присвоим такой конструкции название Р-путь ( процедурный путь) .
- Обработкой сообщения, когда явного вызова метода нет, но в результате работы "вызывающего" метода порождается сообщение, которое должно быть обработано "вызываемым" методом.
- Для второго случая "вызываемый" метод может породить другое сообщение, что приводит к возникновению цепочки исполнения последовательности методов, связанных сообщениями. Подобная цепочка носит название ММ-путь (путь метод/сообщение) . ММ-путь заканчивается, когда достигается метод, который при отработке не вырабатывает новых сообщений (т. е. вырабатывает "сообщение покоя").
Пример ММ-путей приведен на рисунке 1.
Данная конструкция отражает событийно управляемую природу объектно-ориентированного программирования
Рисунок 1 - Пример MM-путей и P-путей в графовой модели класса
Она может быть взята в качестве основы для построения графовой модели класса или объектно-ориентированной программы в целом. На рисунке 1 можно выделить четыре ММ-пути (1-4) и один P-путь (5):
msg a метод 3 msg 3 метод 4 msg d
msg b метод 1 msg 1 метод 4 msg d
msg b метод 1 msg 2 метод 5
msg c метод 2
call метод 5
Здесь класс изображен как объединенное множество
методов.
Введем следующие обозначения:
- Kmsg - число методов класса, обрабатывающих различные сообщения;
- Kem - число методов класса, которые не закрыты от прямого вызова из других классов программы.
- Если рассматривать класс как программу P, то можно выделить следующие отличия от программы, построенной по процедурному принципу:
- Значение Kext (число точек входа, которые могут быть вызваны извне) определяется как сумма методов - обработчиков сообщений Kmsg и тех методов, которые могут быть вызваны из других классов программы Kem. Это определяется разработчиком путем разграничения доступа к методам класса с помощью спецификаторов доступа при написании методов.
Таким образом, Kext = Kmsg + Kem , имеет новый по сравнению с процедурным программированием физический смысл.
- Принцип соединения узлов в графе, отражающий два возможных типа вызовов методов класса (через ММ-пути и Р-пути ).
В ходе интеграционного тестирования должны быть проверены все возможные внешние вызовы методов класса, как непосредственные обращения, так и вызовы, инициированные получением сообщений.
Данные - члены класса (данные, описанные в самом
классе, и унаследованные от классов-родителей видимые
извне данные) рассматриваются как " глобальные
переменные ", они должны быть протестированы отдельно
на основе принципов тестирования потоков данных.
Когда класс программы P протестирован, объект данного
класса может быть включен в общий граф G программного
проекта, содержащий все ММ-пути и все вызовы методов
классов и процедур, возможные в программе.
Рисунок 2
Таким образом определяется классовая модель проекта для тестирования объектно-ориентированной программы. Она поддерживает итерационный инкрементальный процесс разработки программного обеспечения.
Рисунок 3 – Дерево классов проекта и модель класса,
входящего в программный проект
Тестирования программы , представленной в виде классовой модели программного проекта, включает в себя несколько этапов, соответствующих уровням тестирования (Рисунок 4):
На первом уровне проводится тестирование методов каждого класса программы, что соответствует этапу модульного тестирования.
На втором уровне тестируются методы класса, которые образуют уровень интеграционного тестирования каждого класса.
На третьем уровне протестированный класс включается в общее дерево классов программного проекта. Здесь становится возможным отслеживать реакцию программы на внешние события
Второй и третий уровни данной модели соответствуют этапу интеграционного тестирования .
Объектно-ориентированный подход использует иерархическую модель программного проекта. Приведенная на рисунке схема иллюстрирует способ применения. Каждый класс рассматривается как объект модульного и интеграционного тестирования . Сначала каждый метод класса тестируется как модуль по выбранному критерию C. Затем класс становится объектом интеграционного тестирования . Далее осуществляется интеграция всех методов всех классов в единую структуру –
классовую модель проекта, где протестированные модули входят в общий граф в виде узлов (интерфейсов вызова) без учета их внутренней структуры, а их детальные описания образуют контекст всего программного проекта.