Шаг 11.
Правила тестирования. Восходящее и нисходящее тестирование

    На этом шаге мы рассмотрим технологию восходящего и нисходящего тестирования.

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

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

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

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

    К сожалению, часто неверно понимают функции, выполняемые заглушками. Так, порой можно услышать, что заглушка должна выполнять лишь запись сообщения, устанавливающего: "Модуль подключился". В большинстве случаев эти утверждения ошибочны. Когда модуль A вызывает модуль B, A предполагает, что B выполняет некую работу, то есть модуль A получает результаты работы модуля B. Когда же модуль B просто возвращает управление или выдает некоторое сообщение без передачи в A определенных осмысленных результатов, модуль A работает неверно не вследствие ошибок в самом модуле, а из-за несоответствия ему модуля-заглушки. Более того, результат может оказаться неудовлетворительным, если "ответ" модуля-заглушки не меняется в зависимости от условий теста. Если заглушка всегда возвращает один и тот же фиксированный результат вместо конкретного значения, предполагаемого вызывающим модулем именно в этом вызове, то вызывающий модуль сработает как ошибочный (например, зациклится) или выдаст неверное выходное значение. Следовательно,


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

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

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

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

    Проведем сравнение нисходящего и восходящего тестирования [1].

Таблица 1. Сравнение восходящего и нисходящего тестирования
Преимущества Недостатки
Нисходящее тестирование
1. Имеет преимущества, если ошибки, главным образом, в верхней части программы. 1. Необходимо разрабатывать модули-заглушки, которые часто оказываются сложнее, чем кажется вначале.
2. Раннее формирование структуры программы позволяет провести ее демонстрацию пользователю и служит моральным стимулом. 2. Может оказаться трудным или невозможным создать тестовые условия.
3. Сложнее оценка результатов тестирования.
4. Стимулируется незавершение тестирования некоторых модулей.
Восходящее тестирование
1. Имеет преимущества, если ошибки, главным образом, в модуле нижнего уровня. 1. Программа как единое целое не существует до тех пор, пока не добавлен последний модуль.
2. Легче создавать тестовые примеры.
3. Проще оценка результатов.

    Значительное повышение корректности и надежности программ достигается применением двойного или N-кратного программирования (Duplication Check - двойной просчет, двойная проверка).

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

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

    Для устранения такого рода недоразумений нужно тщательно проверять набор тестов ("тестировать" тесты).

   


(1) Майерс Г. Надежность программного обеспечения. - М.: Мир, 1980.

    На следующем шаге мы рассмотрим типы тестов.




Предыдущий шаг Содержание Следующий шаг