- •4.9.1. Изменяемость
- •4.9.2. Классы операций
- •98 Глава 4
- •4.9.3. Полнота
- •100 Глава 4
- •4.9.5. Операции egual, similar и copy
- •102 Глава 4
- •104 Глава 4
- •5. Исключительные ситуации
- •108 Глава 5
- •110 Глава 5
- •6.2.1. Сигнализация об исключительных ситуациях
- •5.2.2. Обработка исключительных ситуаций
- •112 Глава 5
- •5.2.3. Предложение resignal
- •6.2.4. Необрабатываемые исключительные ситуации
- •114 Глава 5
- •6.2.3. Предложение resignal
- •5.2.4. Необрабатываемые исключительные ситуации
- •116 Глава 5
- •118 Глава 5
- •118 Глава 5
- •120 Глава 5
- •122 Глава 5
- •124 Глава 5
- •128 Глава 6
- •130 Глава 6
- •6.2.1. Реализация итераторов
- •6.2.2. Использование итераторов
- •132 Глава 6
- •134 Глава 6
- •136 Глава 6
- •138 Глава 6
- •140 Глава 7
- •142 Глава 7
- •7.2. Абстракция данных
- •144 Глава 7
- •146 Глава 7
- •148 Глава 7
- •150 Глава 7
- •7.4. Генераторы
- •162 Глава 7
- •154 Глава 7
- •156 Глава 7
- •162 Глава 8
- •164 Глава 8
- •166 Глава 8
- •168 Глава 8
- •170 Глава 9
- •172 Глава 9
- •174 Глава 9
- •176 Глава 9
- •9.1.3. Пример
- •178 Глава 9
- •180 Глава 9
- •182 Глава 9
- •184 Глава 9
- •186 Глава 9
- •188 Глава 9
- •190 Глава 9
- •192 Глава. 9
- •194 Глава 9
172 Глава 9
иртание и отладка
термов (х >- 0 есть сокращение от х =•= 0 1 х> 0), то оно может быть удовлетворено двумя способами. Это оставляет нам ситуации, при которых требования в предложении requires удовлетворяются:
1. х = 0 & .00001 < epsilon < .001.
2. х > 0 & .00001 < epsilon < .001.
Любой набор тестировочных данных для программы sqrt должен обязательно удовлетворять каждому из этих условий.
Сформировать набор данных, который будет проверять все условия, заданные в предложении requires спецификации, довольно затруднительно. Может оказаться затруднительным даже установление того, какие условия должны быть проверены. Например, в приведенной выше спецификации программы sqrt мы ' предполагаем, что программа иногда возвратит точный результат, иногда результат, чуть меньший, чем точное значение квадратного корня, а иногда — чуть больший. Программа же, которая всегда возвращает чуть большее или равное значение, будет вполне приемлемой. Мы окажемся не в состоянии подыскать данные, при которых возвращаемый результат чуть меньше ожидаемого, однако мы не можем знать этого без анализа текста программы. Фактически, без анализа текста программы мы не имеем представления о том, какие классы входных данных разбивают результаты на три категории.
Тем не менее мы должны внимательно проанализировать предложение effects и попытаться отыскать данные, которые ему удовлетворяют. Например, рассмотрим операцию intset$member:
member = proc (s: intset, х: int) returns (bool) effects Возвращает значение true, если х принадлежит s; в противном
случае возвращается значение false.
Предложение effects в этой спецификации представляет собой конъюнкцию: либо х принадлежит s, либо нет.
Часто тестирование, основанное на анализе предложения effects, проверяет функционирование программ обработки ошибок. Отсутствие сигнала о возникновении исключительноя ситуации при запрещенных значениях входных параметров является столь же серьезной ошибкой, что и неверная работа программы при нормальных значениях. Следовательно, данные теста должны проверять все возможные реакции программы. Рассмотрим, например, следующую спецификацию:
search^ proc (a: array lint], х: int) returns': int) signals (notJn) •-' effects Если х не принадлежит а, то возвращается i, такое, что a [i]=x;
в противном случае — сообщение not-in.
анной ситуации мы должны включить в проверку оба теста—. тай, когда х принадлежит а, и случай, когда х не принадле-: • а. Аналогично, если при выполнении программы sqrt возни-ают исключительные ситуации, а не значения, указанные в пред-ожении requires, то мы должны включить тесты, проверяющие акие ситуации.
Проверка граничных условий. Программа должна быть всегда Проверена с «типичными» входными значениями — например, Массивом или набором, содержащим несколько элементов, или целым числом, находящимся в границах между максимальным и 1минимальным значением, выдаваемым программой. Важно также ^проверить программу с нетипичными входными данными, которые Принято называть граничными.
t Анализ всех случаев, обусловленных предложением requires, ^Предполагает также проверку ряда граничных ситуаций — на-; пример, случай, при котором программа sqrt должна извлечь квадратный корень из нуля. Однако такой анализ не учитывает 'все граничные ситуации. Весьма важно проверить максимально возможное число таких ситуаций. Подобные проверки позволяют выявить два распространенных вида ошибок:
1. Логические ошибки, при которых обработка граничного условия не приводит к выходу на специальную подпрограмму его обработки, и
2. Отсутствие проверки условий, которые могут привести к возникновению исключительной ситуации в языке, расположенном на более низком уровне, или в аппаратной части (например, арифметическое переполнение).
Для составления тестов, проверяющих второй тип ошибки, хорошим приемом является использование проверочных данных, покрывающих все комбинации максимально и минимально допустимых значений всех тех числовых аргументов, изменение которых происходит в пределах некоторых границ. Например, тесты для программы sqrt должны включать случаи со значением для epsilon, очень близким к 0.001 и 0.00001. При работе со строковыми данными тесты должны включать пустую строку и строку из одного символа. Для массивов мы должны проверить пустой и односимвольный массивы.
Наложение ошибок. Другой вид граничного условия возникает в том,случае, когда один изменяемый объект связывается с двумя различными формальными параметрами, рассмотрим, например, процедуру
append, array -= proc (a I, a2: array [int]) modifies al и a2 effects Удаляет элементы из a2 и помещает их в конец al
К.
