Технологии программирования
Шрифт:
Сравним способ построения тестов при данной стратегии с исчерпывающим входным тестированием стратегии "черного ящика". Неверно предположение, что достаточно построить такой набор тестов, в котором каждый оператор исполняется хотя бы один раз. Исчерпывающему входному тестированию может быть поставлено в соответствие исчерпывающее тестирование маршрутов. Подразумевается, что программа проверена полностью, если с помощью тестов удается осуществить выполнение этой программы по всем возможным маршрутам
Последнее утверждение имеет два слабых пункта: во-первых, число не повторяющих друг друга маршрутов — астрономическое; во-вторых, даже если каждый маршрут может быть проверен, сама программа может содержать ошибки (например, некоторые маршруты пропущены).
Свойство пути выполняться правильно для одних данных и неправильно для других — называемое чувствительностью к данным, наиболее часто проявляется за счет численных погрешностей и погрешностей усечения методов. Тестирование каждого из всех маршрутов одним тестом не гарантирует выявление чувствительности к данным.
В результате всех изложенных выше замечаний отметим, что ни исчерпывающее входное тестирование, ни исчерпывающее тестирование маршрутов не могут стать полезными стратегиями, потому что оба они нереализуемы. Поэтому реальным путем, который позволит создать хорошую, но, конечно, не абсолютную стратегию, является сочетание тестирования программы несколькими методами.
Рассмотрим пример тестирования оператора
при использовании разных критериев полноты тестирования.
При критерии покрытия условий требовались бы два теста: А = true, В = false и А = false, В = true. Но в этом случае не выполняется then-предложение оператора if.
Существует еще один критерий, названный покрытием решений/условий. Он требует такого достаточного набора тестов, чтобы все возможные результаты каждого условия в решении выполнялись, по крайней мере, один раз; все результаты каждого решения выполнялись тоже один раз и каждой точке входа передавалось управление, по крайней мере, один раз.
Недостатком критерия покрытия решений/условий является невозможность его применения для выполнения всех результатов всех условий. Часто подобное выполнение имеет место вследствие того, что определенные условия скрыты другими условиями. Например, если условие AND есть ложь, то никакое из последующих условий в выражении не будет выполнено. Аналогично, если условие OR есть истина, то никакое из последующих условий не будет выполнено. Следовательно, критерии покрытия условий и покрытия решений/условий недостаточно чувствительны к ошибкам в логических выражениях.
Критерием, который решает эти и некоторые другие проблемы, является комбинаторное покрытие условий. Он требует создания такого числа тестов, чтобы все возможные комбинации результатов условия в каждом решении и все точки входа выполнялись,
В случае циклов число тестов для удовлетворения критерию комбинаторного покрытия условий обычно больше, чем число путей.
Легко видеть, что набор тестов, удовлетворяющий критерию комбинаторного покрытия условий, удовлетворяет также и критериям покрытия решений, покрытия условий и покрытия решений/условий.
Таким образом, для программ, содержащих только одно условие на каждое решение, минимальным является критерий, набор тестов которого вызывает выполнение всех результатов каждого решения, по крайней мере, один раз; передает управление каждой точке входа (например, оператор CASE).
Для программ, содержащих решения, каждое из которых имеет более одного условия, минимальный критерий состоит из набора тестов, вызывающих все возможные комбинации результатов условий в каждом решении и передающих управление каждой точке входа программы, по крайней мере, один раз.
Деление алгоритма на типовые стандартные структуры, согласно проектной процедуре кодирования текста модуля (метода) из пятой главы учебника, позволяет минимизировать усилия программиста, затрачиваемые им на тестирование. Запрет на вложенные структуры как раз и объясняется излишними затратами на тестирование. Использование цепочки простых альтернатив с одним действием или структуры ВЫБОР вместо вложенных простых АЛЬТЕРНАТИВ значительно сокращает число тестов!
11.5. ПРОЕКТИРОВАНИЕ ТЕСТОВ БОЛЬШИХ ПРОГРАММ
Проектирование тестов больших программ пока в большей мере остается искусством и в меньшей мере является наукой. Чтобы построить разумную стратегию тестирования, надо разумно сочетать оба этих два крайних подхода и пользоваться математическими доказательствами.
Восходящее тестирование. Сначала автономно тестируются модули нижних уровней, которые не вызывают других модулей. При этом достигается такая же их высокая надежность, как и у встроенных в компилятор функций. Затем тестируются модули более высоких уровней вместе с уже проверенными модулями и т. д. по схеме иерархии.
При восходящем тестировании для каждого модуля необходима ведущая программа. Это монитор или драйвер, который подает тесты в соответствии со спецификациями тестов. Ряд фирм выпускает промышленные драйверы или мониторы тестов.
Нисходящее тестирование. При этом подходе изолированно тестируется головной модуль или группа модулей головного ядра. Программа собирается и тестируется сверху вниз. Недостающие модули заменяются заглушками.
Достоинства нисходящего тестирования: этот метод совмещает тестирование модуля с тестированием сопряжений и частично тестирует функции модуля. Когда уже начинает работать ввод/вывод модуля, удобно готовить тесты.