Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
45
Добавлен:
23.03.2015
Размер:
884 Кб
Скачать

178 Глава 9

9.1.4. Тестирование итераторов

Составление тестов для итераторов эквивалентно составлению тестов для процедур. Единственное любопытное отличие заклю­чается в том, что маршруты в спецификациях итераторов сходны с маршрутами для циклов. Другими словами, мы должны быть уве­рены в том, что в набор тестов включены случаи, когда итерация выполняется дважды и трижды, а также, если это возможно, не выполняется ни разу. Например, рассмотрим итератор primes:

primes = iter (n: int) yields (int)

effects Если n^ 2, то выдаются все простые числа, меньшие или равные n; в противном случае не выдается ничего.

Тесты должны включать случаи для n, равного 1, 2 и 3. Необхо­димость в большем числе тестов определяется на основе реализа­ции итератора.

9.1.6. Тестирование типов данных

При тестировании типов данных мы, как обычно, создаем тесты на основе анализа спецификации и реализации каждой из опера­ций. Теперь мы должны проверить операции не по отдельности, а целыми группами, поскольку некоторые операции (конструкторы и примитивные конструкторы) создают объекты, используемые при тестировании других операций. Например, в операциях intset конструкторы create, insert и delete должны быть исполь­зованы для генерации аргументов для других операций и друг для друга. (Спецификация для intset повторена на рис. 9.3.) intset = data type is create, insert, delete, member, size, elements Назначение

Наборы intset представляют собой неограниченные математические наборы целых чисел. Эти наборы изменяемы: операции insert и delete добавляют и удаляют из набора числа. Операции create == proc ( ) returns (intset)

effects Возвращает новый пустой набор intset. insert == proc (s: intset, x: int)

modifies s effects Добавляет x к элементам s; после завершения операции, spost ==

= s (J {x), где Spost ^ть набор значений в s при возврате из intset. delete s= proc (s: intset, x: int)

modifies s

effects Удаляет x из s (т.е. Spogi == s — (x})« member == proc (s: intset, x; int) returns (tool) ; effects Возвращает (x ^ s). 'size = proc (s: intset) returns (int)

effects Возвращает число элементов в s. elements = iter (s: intset) yields (int) requires s не модифицируется телом цикла.

effects Создает влементы s, по одному и в произвольном порядке. vend Intset Рис. 9,3. Спецификация intset.

Уестирование и отладка

Мы начнем с просмотра маршрутов в спецификациях. Мар-^щруты в спецификациях операций member и elements очевидны. Для операции member мы должны включить случаи, которые выдают в качестве результата true и false. Поскольку elements является итератором, мы должны просмотреть по крайней мере маршруты длиной нуль, единица и двойка. Следовательно, нам необходимы наборы intset, содержащие нуль, один и два элемента. Пустой набор intset и одноэлементный набор intset должны также проверять граничные условия. Итак, мы можем начать со сле­дующих наборов: 1) пустой набор intset, получаемый обращением к intset$create ( ); 2) одноэлементный набор intset, полученный размещением числа 3 в пустом наборе intset; 3) двухэлементный набор intset, получаемый размещением в пустом наборе чисел 3 и 4.

Для каждого из них мы должны выполнить обращения к mem­ber, size и elements, а затем проверить результаты. В случае с mem­ber мы должны сделать обращения, для которых элемент принад­лежит набору, а в остальных — не принадлежит.

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

При размещении элемента, уже принадлежащего набору, раз­мер набора intset остается прежним, следовательно, необходимо проанализировать случай, когда мы дважды помещаем в набор intset один и тот же элемент. Аналогичным образом, размер на­бора intset уменьшается в том случае, если имеющийся в нем эле­мент удаляется. Следовательно, необходимо учесть ситуацию, в которой элемент удаляется после его размещения и удаляется элемент, не принадлежащий набору. Мы можем добавить следую­щие дополнительные наборы: 1) набор, полученный из пустого набора двукратным размещением в нем числа 3; 2) набор, полу­ченный размещением числа 3 и его последующим удалением; 3) набор, полученный размещением числа 3 и удалением числа 4.

Для нахождения скрытых маршрутов необходимо отдельно выделить маршруты для конструкторов. Операция insert должна работать правильно вне зависимости от того, принадлежал ли уже вновь размещаемый элемент набору или нет. Это относится также и к операции delete. Такой подход дает три только что рас­смотренных случая.

Разумеется, мы должны дополнительно рассмотреть маршруты в реализациях операций. Рассмотренные случаи покрывают реа­лизации, использующие массив без дублирующих элементов (рис. 9.4). Единственная возможная проблема связана с содержа­щей цикл операцией member. Для учета всех маршрутов в этом

м

Соседние файлы в папке POSIBNIK