Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Элементы тестирования






Тестирование – это выполнение программы с целью установить наличие ошибок.

Рассмотрим тестирование как составную часть отладки. Основная трудность тести­рования связана с его целью – заставить программу сбиться, т.е. отнестись к ней деструктивно. Автору программы трудно относиться к ней критично, поскольку поиск недостатков в плодах своей работы противоречит человеческой психологии, однако для отладки это необходимо.

Начнем с нескольких общих замечаний.

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

§ Тестирование имеет этапы, аналогичные этапам программирования: постановка задачи, проектирование, написание и проверка тестов, выполнение программы на тестах, изучение результатов.

§ Создавая набор тестов, необходимо для каждого теста описать ожидаемые зна­чения выходных данных или результатов их обработки.

§ Нужно проверять, делает ли программа то, для чего она предназначена, а так­же, не делает ли она того, чего не должна делать.

§ Если набор тестов велик, то сначала программа проверяется на более простых тестах, способных выявить более очевидные ошибки.

§ Ошибки имеют свойство скапливаться. Отсюда парадоксальный вывод – чем больше ошибок найдено в некоторой части программы, тем больше шансов, что там есть еще. Поэтому данную часть программы нужно проверить с уси­ленным вниманием.

§ Не предполагайте, что тест будет использован только один раз.

§ Не упрощайте программу, чтобы облегчить тестирование.

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

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

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

Крайним случаем такого подхода является исчерпываю­щее входное тестирование – в качестве тестов используются все возможные экземпляры данных. Однако это практически невозможно, поэтому нужно искать наборы входных данных, которые ограничены разумными пределами, но достаточно представительны.

Реальные способы тестирования с управлением по данным основаны на том, что множество входных данных можно разбить на классы эквивалентности так, что все экземпляры из некоторого класса эквивалентности дают одинаковые результаты.

На­пример, при вычислении корней квадратного уравнения ах2+bх+с=0 по его действи­тельным коэффициентам все тройки чисел (а, b, с), для которых b2-4ас< 0, должны давать один и тот же ответ. Поэтому вместо тестирования программы для всех таких троек можно проверить только одну. Таким образом, используется набор тестов, пред­ставляющих свои классы эквивалентности.

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

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

Итак, для тестирования важен отбор тестов, дающих максимальную отдачу с точки зрения выявления ошибок.

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

1. Готовятся тесты для каждой ситуации и каждой возможности, описанной в спецификации. К ним добавляются тесты для границ областей допусти­мых значений входных данных, областей выходных данных, для всех недо­пустимых условий.

2. По тексту программы проверяется, все ли ветвления выполняются на подоб­ранных тестах в каждом направлении. Если необходимо, добавляются соответ­ствующие тесты.

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

4. Проверяется чувствительность программы к отдельным особым значениям входных данных; при необходимости тесты добавляются.

Пример 1. Рассмотрим процедуру simpdivisors, печатающей разложение числа типа integer на простые сомножители.

procedure simpdivisors(n: integer);

{Печать разложения натурального n на простые делители}

var divisor: integer; {очередной делитель}

Begin

if n < 0

then begin write(n, ' = -'); n: = -n end

else write(n, ' = ');

if n< = 1 then write(n);

divisor: = 2;

while n > 1 do

Begin

if n mod divisor = 0 then

Begin

write(divisor, ' '); n: = n div divisor

End

else divisor: = divisor+1

End

End;

Спецификация процедуры проста. Она должна печатать разложение числа типа integer в виде последовательности сомножителей, разделенных пробелами, причем количество появлений сомножителя равно его степени в разложении числа. Общий вид печати – " число = разложение", например, 13 = 13 или -10 = -2 5.

Каждый тест – это одно целое число. Вначале согласно спецификации возьмем пограничные натуральные значения (в типе integer) -32 768 и 32 767. Поведение данной процедуры для недопустимых значений не описано, поэтому добавлять недо­пустимые значения в данном случае некорректно. Однако граничные значения могут быть как у входных, так и у выходных данных.

Границу у выходных данных можно связать с длиной последовательности сомножителей. Разложение простых чисел со­стоит из одного сомножителя, поэтому добавим наименьшее и наибольшее (в типе integer) простые числа 2 и 32749. Самое длинное разложение получается у макси­мальной степени числа 2 в типе integer – отрицательного числа -32 768, но оно уже есть. Наконец, добавим какие-нибудь промежуточные значения, положительное и от­рицательное, например 72 и -111.

С помощью текста процедуры убедимся, что на данных тестах ветвления выпол­няются в каждом направлении, а тело цикла – один и много раз. Однако тело цикла не выполняется ни разу, если аргумент равен -1, 0 или 1. Из этих особых значений добавим 0 и -1.

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

Входные данные Ожидаемые выходные данные
-32768 -32768 = -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
  32767 = 7 31 151
  2 = 2
  32749 = 32749
  72 = 2 2 2 3 3
-111 -111 = -3 37
  0 = 0
-1 -1 = -1

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

program driver;

procedure simpdivisors(n: integer);

End;

Begin

simpdivisors(-32768); writeln;

simpdivisors(32767);

writeln;

simpdivisors(0); writeln;

End.

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

-32768 = - -32768

С учетом обработки остальных отрицательных чисел этот результат однозначно указы­вает, что -32 768 при выполнении n: =-n не превратилось в 32 768, которого попро­сту нет в типе integer. Ошибка связана с тем, что в процедуре не учтены особенно­сти машинного представления целых чисел.

В данной ситуации возможны два выхода. Можно изменить спецификацию, сузив область данных (от -32 767 до 32 767), однако лучше в процедуру добавить проверку параметра на равенство -32 768 и дополнительную обработку этого значения. Естест­венно, после этого нужно повторить тестирование и убедиться, что все в порядке.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.