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

Лекция № 10

Тестирование и отладка программ

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

Дейкстра: "Никакое тестирование не может подтвердить правильность программы: в лучшем случае, оно может показать только ее ошибочность".

Отладка – локализация и исправление ошибок.

Виды программных ошибок Способы их обнаружения

1. Синтаксические Статический контроль и диагностика компилятором и компоновщиком

2. Ошибки выполнения, выявляемые Динамический контроль:

автоматически:

а) переполнение, потеря порядка, ... - аппаратурой процессора (Вопрос 1)

б) несоответствие типов - run-time системы программирования

в) зацикливание - операционной системой – по превы-

шению лимита времени задачи

3. Программа не соответствует специ- Целенаправленное тестирование

фикации

4. Спецификация не соответствует Испытания, бета-тестирование

требованиям – ошибка спецификации

Глубина контроля 1-го вида зависит и от языка, и от компилятора. Строгая типизация весьма полезна: DO 3 I = 1.3 – “точка стоимостью 800 млн $” (вместо запятой) – ошибка в Фортран-программе бортового вычислителя ракеты к Венере [1]. Вопрос 2.

Набор ошибок 2-го вида может быть расширен программистом: контроль можно программировать с помощью утверждений (asserts) проверок, вставляемых в код. Это полезно для проверки правдоподобности промежуточных результатов вычислений и допустимости значений фактических параметров подпрограмм.

Собственно процесс тестирования направлен на выявление ошибок 3 и 4 видов. Большинство программистов сами исправляют 99% своих текущих ошибок. Однако порядка одной ошибки на 100 строк кода обычно еще остается, когда программист сдает работу тестеру, утверждая, что ошибок в ней нет [2].

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

Ключевой вопрос – полнота тестирования: какое количество каких тестов гарантирует возможно более полную проверку программы ? Исчерпывающая проверка на всем множестве входных данных недостижима. Пример: программа, вычисляющая функцию двух переменных: Y = f (X, Z). Если X, Y, Z – real, то полное число тестов (232)2 = 264 ≈ 1031. Если на каждый тест тратить 1 мс, то 1031 мс = 800 млн лет (отсюда видно, что ошибка FDIV Pentium’а вполне простительна). Все траектории выполнения кода также невозможно воспроизвести. В [1] приведена программа из двадцати строк кода (цикл и несколько операторов IF), у которой 1017 возможных путей выполнения.

Следовательно:

  • В любой нетривиальной программе на любой стадии ее готовности содержатся необнаруженные ошибки

  • Продолжительность тестирования – технико-экономическая проблема: компромисс между временем и полнотой. Поэтому нужно возможно меньшее количество хороших тестов с желательными свойствами:

  • Детективность: тест должен с большой вероятностью обнаруживать возможные ошибки.

  • Покрывающая способность: один тест должен выявлять как можно больше ошибок.

  • Воспроизводимость: ошибка должна выявляться независимо от изменяющихся условий (например, от временных соотношений) – это трудно достижимо для время-зависимых программ, реультаты которых часто невоспроизводимы.

Это благие пожелания; для направленного выбора руководствуются критериями выбора тестов. Критерий должен показать, когда некоторое конечное множество тестов достаточно для проверки программы с некоторой полнотой.

Два вида критериев:

  • Функциональные – если тесты составляются исходя из спецификации программы (тестирование черного ящика). Проверяется правильность выполнения программой всех ее заданных функций. Именно этим критериям в основном и следуют при независимом тестировании.

  • Структурные – если тесты составляются исходя из текста программы (тестирование прозрачного ящика). Проверяется правильность работы при прохождении всех участков кода. Эту работу программисты выполняют постоянно в ходе разработки.

Вид критерия Что должно обеспечивать множество тестов

А. Функциональные

1. Тестирование классов вх. данных ! Содержать представителей всех вх или вых

2. Тестирование классов вых. данных ! классов и точки на границах классов

3. Тестирование функций Каждая функция внешнего интерфейса должна быть проверена >= 1раза

Б. Структурные

  1. Тестирование команд Каждая команда (оператор) д.б. выполнена

>= 1раза

  1. Критерий С1 – тестир. ветвей Каждая ветвь д.б. выполнена >= 1раза

  2. Критерий С2 – тестир. путей Каждый путь в графе программы д.б.

выполнен >= 1раза (Вопрос 3)

На рис 10-1 а) видно отличие тестирования команд (достаточен один тест) от С1 (необходимы два теста как минимум). Рис 10-1 б) иллюстрирует отличие С1 (достаточно двух тестов, покрывающих пути 1, 4 или 2, 3) от С2 (необходимо 4 теста для всех четырех путей). С2 в принципе недостижим в реальных программах из-за их цикличности, поэтому ограничиваются тремя путями для каждого цикла: 0, 1 и N повторений цикла.

Идея назначения классов эквивалентности вх/вых данных для функционального тестирования основана на разумном предположении, что программа на всем классе ведет себя так же, как на его одном представителе. Классы назначаются исходя из семантики решаемой задачи. В таблице 1 дан пример тестирования классов выходных данных: минимальный набор тестов для программы нахождения вещественных корней квадратного уравнения ax2 + bx + c = 0 (Грюнбергер, 1968).

Рис.10-1. Траектории вычислений при структурном тестировании

Таблица 1

a

b

c

Ожидаемый результат

Что проверяется

1

2

-5

2

x1=2, x2=0.5

Случай вещественных корней

2

3

2

5

Сообщение

Случай комплексных корней

3

3

-12

0

x1=4, x2=0

Нулевой корень

4

0

0

10

Сообщение

Неразрешимое уравнение

5

0

0

0

Сообщение

Неразрешимое уравнение

6

0

5

17

Сообщение

Не квадратное уравнение (деление на 0)

7

9

0

0

x1=x2=0

Корень из 0

Таким образом, для этой программы предлагается минимальный набор из 7 функциона-льных тестов, исходя из 7 классов выходных данных.

Пример, где назначаются классы входных данных – на рис. 10-2. Здесь классы- точечные множества; внутри области А они отмечены штриховкой; символом * отмечены представители классов - тестовые значения. На рис. 10-2 предложен минимальный набор из 18 тестов – по одному для каждого класса и границы –

стороны многоугольника, ограничивающего область А. В состав тестового набора следует включать значения, непосредственно примыкающие к граничным. Например, если допустимые входные значения – целые от 1 до 99, то для тестирования допусти-мых данных можно выбрать 1 и 99, а для недопустимых – 0 и 100. Если программа получает 8 входных данных, то нужно предусмотреть 3 теста: ввод 8, 7 и 9 данных.

Запись классов эквивалентности входных данных в текстовой форме является частным случаем плана тестирования, пример которого приведен на рис. 10-3. Заметим, что классы эквивалентности могут пересекаться, как в этом примере (классы 1.2.4.1 и 1.2.4.3) – это приводит к некоторой избыточности, но не страшно. Задание 4.

Рис 10-2. Классы входных данных для тестирования

1. Ввод числа

1.1 Допустимые варианты

1.1.1 Числа от 0 до 99

1.2 Недопустимые варианты

      1. 0

      2. > 99

      3. Отрицательные числа

      4. Буквы и другие нечисловые символы

        1. Буквы

        2. Символы с ASCII-кодами, меньшими кода 0

        3. Символы с ASCII-кодами, большими кода 9

2. Ввод первой буквы имени

2.1 Допустимые варианты

2.1.1 Первый символ является заглавной буквой

<и т.д.>

Рис 10-3. Классы входных данных: фрагмент плана тестирования

Различие между функциональным и структурным тестированием относительно. Для интерактивных и реального времени программ оно стирается: входные данные – различные последовательности действий пользователя или внешних событий – однозначно отображаются на различные траектории переключения состояний программы, т.е. пути в ней. Таких траекторий – необозримо много, поэтому приходится ограничиваться тестированием наиболее вероятных действий пользователя или последовательностей событий, имитируемых специальной тестовой программой. К ним добавляются случайные действия, например, нажатие клавиш в случайные моменты времени. Профессиональные тестеры составляют схемы меню – диаграммы состояний и переходов при вводе диалоговых команд – для контроля полноты прохождения типичных траекторий диалога.

Нагрузочные тесты проверяют работу программы при различных конфигурациях аппаратуры (особенно при минимальных) и при совместном выполнении в мультипро-граммной среде.

Соседние файлы в предмете Информатика