На этом шаге мы рассмотрим некоторые правила тестирования программ.
Рассмотрим некоторые правила тестирования, в которых делается попытка учесть как желательность доказательства правильности контролируемой программы, так и ограниченность человеческих возможностей при проведении такого доказательства [1].
Проход участков. Каждый линейный участок программы должен быть обязательно пройден при выполнении, по крайней мере, одного теста. Очевидно, что в противном случае никакой гарантии в правильности работы всей программы дать будет нельзя.
В том случае, когда выполнение некоторого участка программы меняет порядок выполнения или характер работы других участков, может потребоваться перебор всех ветвей программы, то есть проход по всем возможным путям выполнения программы (многократная проверка требуется, в частности, для участков, содержащих переменные с индексами).
Точность проверки. Контроль арифметических блоков (как и других блоков) производится путем сверки результатов, полученных при выполнении блока, с эталонными результатами. Для арифметических результатов дополнительная сложность заключается в определении точности, с которой необходимо сверять (и, тем самым, вычислять) эталонные и тестовые результаты, с тем, чтобы можно было действительно удостовериться в правильности работы блока.
Дело в том, что величины, входящие в проверяемое арифметическое выражение в зависимости от соотношения их значений и характера производимых над ними операций, вносят различный вклад в результат. Поэтому может оказаться, что неправильно запрограммированное выражение для некоторых тестовых значений величин, входящих в него, будет иметь якобы правильное значение ввиду того, что результат неправильной операции или неверно вычисленный ранее операнд выражения не окажут почти никакого влияния на тестовое (сравниваемое) значение выражения.
Например, для оператора C=A+B из того, что значение C совпало с эталонным значением, не следует, что выражение записано в программе верно, поскольку для случая, когда A>>B, замена плюса на минус не будет обнаружена, если эталонное значение C вычислено с недостаточной точностью. Кроме того, если вычисление А и B не было проверено ранее, то из правильности C нельзя сделать вывод о правильности вычисления B (для случая A>>B).
Таким образом, для того, чтобы быть уверенным в том, что правильный числовой результат, полученный на компьютере, говорит о правильности программы, необходимо следить за промежуточными результатами вычислений, которые не должны выходить за определенный диапазон, устанавливаемый в зависимости от точности вычислений эталонных результатов. Выполнение такого требования может привести к необходимости многократной проверки выражения для различных диапазонов данных.
Минимальность вычислений. Когда продолжительность работы контролируемой программы и, тем самым, количество вычислений и необходимых для контроля тестовых данных зависит от каких-либо параметров, то при контроле их следует выбирать такими, чтобы они минимизировали количество вычислений.
К таким параметрам, например, могут относиться:
Конечно, такая инициализация не должна значительно снижать надежность контроля. Следует заметить также, что значения исходных данных нужно выбирать такими, чтобы изготовление эталонных результатов вручную было, по возможности, облегчено. Например, данные могут быть сначала взяты целочисленными или такими, чтобы при проверке выражений некоторые их слагаемые, уже проверенные ранее, обращались в нуль.
Достоверность эталонов. Нужно обратить внимание и на достоверность процесса получения эталонных результатов. По возможности они должны вычисляться не самим программистом, а кем-то другим, с тем чтобы одни и те же ошибки в понимании задания не проникли и в программу, и в эталонные результаты. Если тесты готовит сам программист, то эталоны нужно вычислять до получения на компьютере соответствующих результатов. В противном случае имеется опасность невольной подгонки вычисляемых значений под желаемые, полученные ранее на компьютере. В качестве эталонных результатов часто используют и данные, полученные при ручной прокрутке программы.
Планирование. При отсутствии планового подхода тестирование обычно сводится к тому, что программист берет какие-то, можно сказать, первые попавшиеся исходные данные и пропускает программу многократно, исправляя ее при обнаружении ошибок и добиваясь того, чтобы получаемые результаты походили на желаемые.
Ясно, что при этом контролируется только некоторая часть блоков и операторов, а остальные выполнятся в первый раз уже во время счета, и будут ли при этом найдены ошибки, имеющиеся в них, зависит только от случая.
На следующем шаге мы продолжим рассмотривать вопросы, связанные с планированием тестирования, в частности, остановимся на восходящем и нисходящем тестировыании.