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

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

· восходящее тестирование;

· монолитное тестирование;

· нисходящее тестирование.

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

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

Рис. 23 Разработка драйверов и заглушек при восходящем интеграционном тестировании

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

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

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

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

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

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

· Процесс тестирования плохо автоматизируется. Преимущество (нет дополнительного программного обеспечения, сопровождающего процесс тестирования) оборачи­ва­ет­ся недостатком. Каждое внесённое изменение требует повторения всех тестов.

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

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

У разных специалистов в области тестирования разные мнения по поводу того, какой из методов более удобен при реальном тестировании программных систем. Йордан доказывает, что нисходящее тестирование наиболее приемлемо в реальных ситуациях [27], а Майерс полагает, что каждый из подходов имеет свои достоинства и недостатки, но в целом восходящий метод лучше [28].

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

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: