На этом шаге мы рассмотрим технологию восходящего и нисходящего тестирования.
При плановом подходе программа проверяется последовательно блок за блоком, причем если программа состоит из центрального блока, который проводит обращения к периферийным блокам, мало связанным друг с другом, то возможны следующие два основных подхода к контролю такой программы, два основных направления тестирования:
При первом, восходящем тестировании, применяемом обычно для небольших программ, сначала тестируют отдельные периферийные блоки, а затем переходят к тестированию центральной части, которая, разумеется, взаимодействует только с отлаженными уже блоками.
При нисходящем тестировании, используемом для достаточно больших программ, параллельно с контролем периферийных блоков (или даже до начала их контроля) производится и контроль центрального блока, выполняемого на компьютере совместно с имитаторами периферийных блоков, называемых заглушками. В задачу имитаторов входит моделирование работы соответствующих блоков с целью поддержать функционирование центрального блока. Обычно заглушки выдают простейший результат, например константу и сообщение о факте своего участия в работе. Вместо постоянной величины на наиболее поздней стадии тестирования может выдаваться и случайная величина в требуемом диапазоне.
Например, для начального контроля программы, включающей в качестве одного из своих блоков вычисление определенного интеграла, заглушка такого блока может возвращать константу. В свою очередь, блок интегрирования сам имеет периферийный блок вычисления значений подинтегральной функции, в качестве заглушки которого поначалу также может быть взята константа или простейшая функциональная зависимость.
К сожалению, часто неверно понимают функции, выполняемые заглушками. Так, порой можно услышать, что заглушка должна выполнять лишь запись сообщения, устанавливающего: "Модуль подключился". В большинстве случаев эти утверждения ошибочны. Когда модуль A вызывает модуль B, A предполагает, что B выполняет некую работу, то есть модуль A получает результаты работы модуля B. Когда же модуль B просто возвращает управление или выдает некоторое сообщение без передачи в A определенных осмысленных результатов, модуль A работает неверно не вследствие ошибок в самом модуле, а из-за несоответствия ему модуля-заглушки. Более того, результат может оказаться неудовлетворительным, если "ответ" модуля-заглушки не меняется в зависимости от условий теста. Если заглушка всегда возвращает один и тот же фиксированный результат вместо конкретного значения, предполагаемого вызывающим модулем именно в этом вызове, то вызывающий модуль сработает как ошибочный (например, зациклится) или выдаст неверное выходное значение. Следовательно,
Практически, оба этих способа редко используются в чистом виде, отдельно один от другого. Обычно ко времени, когда приступают к контролю центрального блока, какие-то простейшие периферийные блоки уже отлажены автономно, и нет необходимости моделировать их работу и разрабатывать заглушки.
Преимуществом ранней отладки центрального блока при нисходящем тестировании является то, что программист быстро получает возможность проверить периферийные блоки в условиях, которые в необходимой степени приближены к реальным. Действительно, центральный блок, снабженный хотя бы и простейшими функциональными возможностями, можно рассматривать как реальную среду, в которую "погружаются" отлаживаемые блоки, добавляемые к центральной части. Добавление отлаживаемых блоков удобно производить по одному для быстрейшего поиска ошибок, возникающих при стыковке с центральным блоком. Подключение каждого нового блока к центральной части позволяет постепенно усложнять испытания, которым подвергается тестируемая программа.
Строгой, корректной процедуры подключения очередного последовательно тестируемого модуля не существует. Единственное правило, которым следует руководствоваться при выборе очередного модуля, состоит в том, что им должен быть один из модулей, вызываемых модулем, предварительно прошедшим тестирование.
Запомните, что даже если изменения вносятся только в одну подпрограмму, то повторному тестированию подлежит вся система. Этот процесс называется тестированием с возвратом. Проверять работу только измененной подпрограммы недостаточно! Недостаточно полное тестирование такого рода повышает вероятность неудач.
Проведем сравнение нисходящего и восходящего тестирования [1].
Преимущества | Недостатки |
---|---|
Нисходящее тестирование | |
1. Имеет преимущества, если ошибки, главным образом, в верхней части программы. | 1. Необходимо разрабатывать модули-заглушки, которые часто оказываются сложнее, чем кажется вначале. |
2. Раннее формирование структуры программы позволяет провести ее демонстрацию пользователю и служит моральным стимулом. | 2. Может оказаться трудным или невозможным создать тестовые условия. |
3. Сложнее оценка результатов тестирования. | |
4. Стимулируется незавершение тестирования некоторых модулей. | |
Восходящее тестирование | |
1. Имеет преимущества, если ошибки, главным образом, в модуле нижнего уровня. | 1. Программа как единое целое не существует до тех пор, пока не добавлен последний модуль. |
2. Легче создавать тестовые примеры. | |
3. Проще оценка результатов. |
Значительное повышение корректности и надежности программ достигается применением двойного или N-кратного программирования (Duplication Check - двойной просчет, двойная проверка).
При этом методе при разных алгоритмах и на разных языках программирования создается несколько вариантов программы. Эти варианты реализуют одни и те же функции и при определенных тестовых данных должны выдавать тождественные результаты. Различие результатов при тестировании указывает на наличие ошибок, по крайней мере, в одном из вариантов. Обычно при разработке вариантов программы используется один и тот же алгоритм, но программы создаются на разных языках, разных компьютерах и разными программистами. На практике применяется программирование с N=2. Практически очень редки случаи, когда реальная программа создавалась в трех и более вариантах.
В заключение заметим, что если исполнение теста приносит результаты, не соответствующие предполагаемым, то это означает, что:
Для устранения такого рода недоразумений нужно тщательно проверять набор тестов ("тестировать" тесты).
На следующем шаге мы рассмотрим типы тестов.