- •«Уральский промышленно-экономический техникум»
- •Технология разработки программного обеспечения: тестирование
- •Структурный метод (метод «Белого (стеклянного) ящика»)
- •Поведенческий метод «Черного ящика»
- •Метод регрессивного тестирования
- •Метод «Серого ящика»
- •Метод опытной эксплуатации
- •Тестирование эргономичности
- •Метод эквивалентного разбиения
- •Метод анализа граничных значений
- •Метод тестирования таблицы решений
- •Отладка программы
- •7.1. Процессы жц верификация и валидация программ
- •7.2. Тестирование программ
- •7.2.1. Статические методы тестирования
- •7.2.2. Динамические методы тестирования
- •7.2.3. Функциональное тестирование
- •7.3. Инфраструктура процесса тестирования пс
- •7.3.1. Методы поиска ошибок в программах
- •7.3.2. Классификация ошибок и тестов
- •7.3.1. Служба тестирования пс
- •7.3.2. Управление процессом тестирования
Метод эквивалентного разбиения
Разработка тестов методом эквивалентного разбиения осуществляется в два этапа:
а) выделение класса эквивалентности;
б) построение тестов.
Классы эквивалентности выделяются путем выбора каждого входного условия (обычно это предложение или фраза в спецификации) и разбиением его на две или более групп. Для выполнения этой операции используют таблицу следующего вида:
Входные условия |
Правильные классы эквивалентности |
Неправильные классы эквивалентности |
Правильные классы эквивалентности соответствуют правильным входным данным программы, а неправильные классы эквивалентности представляют все другие возможные состояния входных условий.
Процесс построения тестов включает в себя:
назначение каждому классу эквивалентности уникального номера;
проектирование новых тестов, каждый из которых покрывает как можно большее число непокрытых правильных классов эквивалентности, пока все правильные классы эквивалентности не будут покрыты тестами;
запись тестов, каждый из которых покрывает один и только один из непокрытых неправильных классов эквивалентности.
Каждый неправильный класс эквивалентности должен быть покрыт индивидуальным тестом. поскольку определенные проверки с ошибочными входами скрывают или заменяют другие ошибки с ошибочными входами.
Метод анализа граничных значений
Опыт показывает, что тесты, исследующие граничные условия, приносят бОльшую пользу, чем тесты, которые их не исследуют.
Определение: граничные условия это ситуации, возникающие непосредственно на, выше или ниже границ входных и выходных классов эквивалентности.
Метод тестирования таблицы решений
Тестирование ТР заключается в том, что проектируется такое количество тестов, которое позволяет покрыть все возможные комбинации условий.
В заключение рассмотрим вопрос об областях применения методов стратегии «черного ящика».
Обращает на себя внимание тот факт, что все методы рассматриваются на разных примерах. Это не является случайностью, так как не любой метод тестирования спецификаций может быть эффективно применен для разрабатываемой программы. Методы эквивалентного разбиения и функциональных диаграмм, как правило, применяются при разработке языковых процессоров, трансляторов и т.п. Метод граничных условий применяется при тестировании программ, осуществляющих статистическую обработку входной информации. Метод тестирования внешних спецификаций может быть применен везде, где в качестве спецификаций процессов обработки используются таблицы или деревья решений .
Однако на практике можно рекомендовать сочетание таких методов, как функциональных диаграмм, таблиц решений и эквивалентного разбиения с методом граничных значений хотя бы для таких граничных условий, которые представляются достаточно явными. Например, при обработке информации из файлов такими явными граничными условиями является пустые файлы данных, файлы с пропущенными записями или с повторяющимися записями для тех спецификаций, где повторения не должно быть.
Цель изучения темы: изучить различные стратегии и методы тестирования.
Стратегии тестирования
Практика работы позволяет выделить две стратегии тестирования:
Черного ящика (функциональное тестирование)
Белого ящика (структурное тестирование)
Стратегия черного ящика - тестирование с управлением по данным (по входу - выходу).
Целью тестирования является выяснение обстоятельств, при которых поведение программы не соответствует спецификации. При таком подходе обнаружение ошибок может быть достигнуто путем исчерпывающего входного тестирования, т.о. в качестве тестовых наборов используются все возможные наборы входных.
Простейшие примеры показывают, что это практически невозможно. Поэтому чтобы не перебирать все возможные значения применяются методы:
Эквивалентного разбиения,
Анализа граничных значений,
Гипотез ошибок.
Метод эквивалентного разбиения состоит в разбиении входной области программы на конечное число классов эквивалентности, при котором каждый тест данного класса эквивалентен в смысле обнаружения ошибок любому другому тесту этого класса.
Разработка тестов методом эквивалентного разбиения происходит в два этапа: выделение классов эквивалентности и построение тестов.
Классы эквивалентности выделяются на основе анализа входных условий спецификации программы, при этом разделяют два типа классов эквивалентности: правильные (соответствуют правильным входным данным) и неправильные (представляющие ошибочные входные данные). Хотя выделение классов является эвристическим процессом, существует ряд правил, позволяющих его формализировать.
Например, если входное условие описывает ситуацию "должно быть", то определяется один правильный класс и по крайней мере один неправильный.
Пример.
Программа рассчитывает функцию
Рисунок 1.
Область допустимых входных значений по определению логарифма:
Рисунок 2.
Область допустимых значений данных (сокращенно ОДЗ) х (2.33333333, 18)
Рисунок 3.
Выделим 3 класса эквивалентности на основе ОДЗ:
Рисунок 4.
Круглые скобки означают, что точка не входит в отрезок, квадратные скобки - точка входит в отрезок, - - это минус бесконечность, + - это плюс бесконечность.
Из каждого класса берется одно значение. Вы может выбрать любое на Ваше усмотрение. Так для класса 1 можно было, с таким же успехом, взять значение 0 или -0.5. Графа "ожидаемый результат" просчитывается вручную или на калькуляторе. Графа "результат" заполняется при тестировании набранной программы. В дальнейшем сравнение ожидаемого результата и результата работы программы позволит Вам сделать вывод, о правильной или неправильной работе Вашей программы.
Метод граничных значений - это дополненный анализом граничных значений входных условий метод эквивалентного разбиения. Для каждого класса эквивалентности выбирается значение, которое входит в класс ("изнутри" класса), значения находящиеся на границе и значения с незначительным отклонением от границы ("рядом" с границей).
Рисунок 5.
Когда мы рассматриваем два смежных класса, граничное значение должно войти только в один из этих классов. В нашем примере границы между классами - это значения x=2.3333 (входит в класс 1) и x=18 (входит в класс 3)
Пример.
Предыдущий пример дополнится новыми значениями.
Рисунок 6.
В класс 1 добавилось граничное значение х=2.333333 и значение расположенное рядом с границей x=2.32
В класс 2 добавились два значения расположенные рядом с границей x=2.34 и x=17.99
В класс 3 добавилось граничное значение х=18 и значение расположенное рядом с границей x=18.01
Применение метода гипотез ошибок основано на интуитивном предположении об ошибках. Составляется список возможных ошибок и исключительных ситуаций, которые могут появиться в программах данного класса. Достаточное научное обоснование метода возможно на основе широкого анализа предметной области и классификации ошибок и исключительных ситуаций.
Пример.
Пусть
необходимо рассчитать функцию f(x)=log
Гипотеза:
для расчета функции f(x) необходимо
рассчитывать
При
больших значения x может произойти
переполнение и, следовательно, может
возникнуть ошибка.
В качестве теста рассчитаем f(3.3*1038)=1.9844908
Стратегия белого ящика - это тестирование с управляемое логикой программы. Стратегия основана на анализе внутренней структуры программы. Стратегия белого ящика включает проверку (покрытие) операторов, решений, условий, покрытие решений / условий, комбинированное покрытие.
Покрытие операторов. Набор текстов должен быть таким, чтобы каждый оператор программы выполнился хотя бы один раз.
Составим
программу для расчета функции f(x)=
#include <iostream.h>
#include <math.h>
#define LG(a,b) log(a)/log(b)
float f (float x)
{
float y1, y2;
y1 = LG(36-2*x, x*x);
y2=LG(3*x-7, x);
return y1+y2;
}
void main()
{
float x,y;
cout<<"\nВведите х \t";
cin>>x;
if ( (x>2+1.0/3) && (x<18) )
{ y=f(x);
cout << "\ny = "<< y;
}
else cout<< "\nНе корректные входные данные";
}
Тесты по методу покрытия операторов
Рисунок 7.
Достаточно взять два значения х. При 2.33333<х<18 (например, х=3), выполняться все операторы, кроме cout <<"\nНе корректные входные данные";
Для его проверки достаточно взять х>=18 или x<=2.3333, например, x=0.
Метод покрытия решений. При покрытии всех решений каждый маршрут выполнения программы должен быть реализован хотя бы один раз.
Пример.
Рисунок.8.
Обозначим ветви условного оператора буквами a, b, c, d. В данном случае существует 4 маршрут выполнения программы: ac, ad, bc, bd. Набор тестов должен быть таким, чтобы каждый маршрут был реализован хотя бы один раз.
Пример.
По координатам точки (х, y) определить принадлежит ли точка осям координат. Фрагмент программы:
if ( x =0) cout <<"\nТочка на оси ОY";
if ( y = 0 ) cout < <"\nТочка на оси ОX";
Рисунок.9.
Тесты по методу покрытия решений
Рисунок 210.
Значения х и у могут быть произвольными. Единственное требование, чтобы они позволяли проверить нужный маршрут.
Покрытие условий.
Для каждого условия необходимо проверить его выполнение и невыполнение хотя бы один раз.
Пример.
По координатам точки (х, y) определить в какой координатной четверти лежит точка.
if ((x > 0) && ( y > 0)) cout <<"\n первая четверть";
if ((x < 0) && ( y > 0)) cout <<"\n вторая четверть";
if ((x < 0) && ( y > 0)) cout <<"\n третья четверть";
if ((x > 0) && ( y > 0)) cout <<"\n четвертая четверть";
Рисунок.11.
Рисунок 12.
Плюс кодирует выполнение условия, минус - не выполнение.
Возьмем такие точки, чтобы условия x>0 и y>0 выполнялись (кодируются +), например x=2 и y=4, при этом условия x < 0 и y < 0 будут не выполнены (кодируются -). Теперь, наоборот, возьмем такие точки, чтобы условия x < 0 и y < 0 не выполнялись (кодируются -), например x= -3 и y= -3, при этом условия x > 0 и y > 0 будут выполнены (кодируются +).
Вы видите, что метод покрытия условий не всегда позволяет проверить все ветви и операторы программы. В данном случае проверены только первый и третий операторы.
Поэтому тест по методу покрытия условий обычно используется совместно с другими тестами. Например, дополняется требованием, чтобы каждый оператор программы был выполнен хотя бы один раз.
Пример.
Рисунок 13.
Добавим тесты для проверки второго и четвертого операторов.
Пример 2.
Для фрагмента программы:
do ( (k <=50) && ( j+k < Q) )
{...}
необходимо проверять условия k<=50, k>50, j+k<Q, j+k>=Q.
Несмотря на очевидные преимущества, критерий покрытия условий не всегда удовлетворяет критерию покрытия решений. Пример, пусть тестируется фрагмент программы:
if (a b)
{ блок операторов 1 }
Для покрытия условий требуется два теста: (а - истинно , b -ложно) и (a -ложно, b истинно). Однако эти тесты не проверяют выполнение блока оператор 1.
Улучшенный тест - покрытие решений/условий. Он требует, чтобы были покрыты все решения и все условия. Получается объединением наборов тестов по методу покрытия решений и покрытия условий.
Еще более серьезное тестирование это комбинированное покрытие. Комбинированное покрытие требует, чтобы хотя бы один раз выполнялись все возможные комбинации условий.
В нашем примере определения координатной четверти для комбинированного покрытия необходимо выполнить 16 тестов:
Рисунок 14.
Соотношения между различными покрытиями.
Рисунок 15.
Для программ содержащих только одно условие на каждом принятии решения минимальным является набор тестов покрытие решений.
Для программ содержащих более одного условия на принятии решения минимальным является тест на покрытие условий/решений.
