В учебных программах по дисциплине "Обеспечение качества и тестирование программ" есть вопросы:
В программе обучения базового уровня International Software Testing Qualifications Board "Сертифицированный тестировщик" указано на необходимость:
"Искусство тестирования программ", Глендфорд Майерс. Москва, Финансы и статистика, 1982 год. 63-74 страницы:
ЭКВИВАЛЕНТНОЕ РАЗБИЕНИЕ
В главе 2 отмечалось, что хороший тест имеет приемлемую вероятность обнаружения ошибки и что исчервывающее входное тестирование программы невозможно. Следовательно, тетирование программы ограничивается использование небольшого подмножества всех возможных входных данных. Тогда, конечно, хотелось бы выбрать для тестирования самое подходящее подмножество (то есть подмножество с наивысшей вероятностью обнраужения большинства ошибок).
Правильно выбранный тест этого подмножества должен обладать двумя свойствами:
- а) уменьшать, причем более чем на единицу, число других тестов, которые должны быть разработаны для достижения заранее определенной цели "приемлемого тестирования";
- б) покрывать значительную часть других возможных тестов, что в некоторой степени свидетельствует о наличии или отсутствии ошибок до и после применения этого ограниченного множества значений входных данных.
Указанные свойства, несмотря на их кажущееся подобие, описывают два различных положения. Во-первых, каждый тест должен включать столько различных входных условий, сколько это возможно, с тем чтобы минимизировать общее число необходимых тестов. Во вторых, необходимо пытаться разбить входную область программы на конечное число классов эквивалентности так, чтобы можно было предположить (конечно, не абсолютно уверенно), что каждый тест, являющиеся представителем некоторого класса, эквивалентен любому другому тесту этого класса. Иными словами, если один тест класс эквивалентности обнаруживают ошибку, то следует ожидать, что и все другие тесты этого класса эквивалентности будут обнаруживать ту же самую ошибку. Наоборот, если тест не обнаруживает ошибки, то следует ожидать, что ни один тест этого класса эквивалентности не будет обнаружить ошибки (в том случае, когда некоторое подмножество класса эквивалентности не попадает в приделы любого другого класса эквивалентности, так как классы эквивалентности могут пересекаться).
Эти два положения составляют основу методологии тестирования по принципу чёрного ящика, известной как эквивалентное разбиение. Второй положение используется для разработки набора "интересных" условий, которые должны быть протестированная, а первое – для разработки минимального набора текстов, покрывающих эти условия.
Примером класса эквивалентности для программы о треугольнике (смотри главу 1) является набор "трёх равных чисел, имеющих целые значения, большие нуля". Определяя этот набор как класс эквивалентности, устанавливают, что если ошибка не обнаружено некоторым тестом данного набора, то маловероятно, что она будет обнаружена другим тестом набора. Иными словами, в этом случае время тестирования лучше затратить на что-нибудь другое (на тестирование других классов эквивалентности).
Разработка тестов методом эквивалентного разбиения осуществляется в два этапа: 1) выделение классов эквивалентности и 2) построение тестов.
Выделение классов эквивалентности
Классы эквивалентности выделяются путем выбора каждого входного условия (обычно это предположение или фраза в спецификации) и разбиением его на две или более групп. Для проведения этой операции используют таблицу, изображенную на рисунке 4.3. Заметим, что различают два типа классов эквивалентности: правильные классы эквивалентности, представляющие правильные входные данные программы, и неправильные классы эквивалентности, представляющие все другие возможные состояния условий (то есть ошибочные входные значения). Таким образом, придерживаются одного из принципов главы 2 о необходимости сосредоточивать внимание не неправильных или неожиданных условиях.
Входные условия Правильные классы эквивалентности Неправильные классы эквивалентности ... ... ... Если задаться входными или внешними условиями, то выделение классов эквивалентности представляет собой в значительной степени эвристический процесс. При этом существует ряд правил:
- Если входное условие описывает область значений (например, "целое данные может принимать значения от 1 до 999"), то определяются один правильный класс эквивалентности (1 <= значение целого данного <= 999) и два неправильных (значение целого данного < 1 и значение целого данного > 999).
- Если входное условие описывает число значений (например, "в автомобиле могут ехать от одного до шести человек"), то определяются один правильный класс эквивалентности и два неправильных (ни одного и более шести человек).
- Если входное условие описывает множество входных значений и есть основание полагать, что каждое занчение программа трактует особо (например, "известны способо передвижения на АВТОБУСЕ, ГРУЗОВИКЕ, ТАКСИ, ПЕШКОМ или МОТОЦИКЛЕ"), то определяется правильный класс эквивалентности для каждого значения и один неправильный класс эквивалентности (например, "НА ПРИЦЕПЕ").
- Если входное условие описывает ситуацию "должно быть" (например, "первым символом идентификатора должна быть буква), то определяется один правильный класс эквивалентности (первый символ – буква) и один неправильный (первый символ – не буква).
- Есть есть любое основание считать, что различные элементы класса эквивалентности трактуюстя программой неодинаково, то данный класс эквивалентности разбивается на меньшие классы эквивалентности. Этот процесс ниже будет кратко проиллюстрирован.
Построение тестов
Второй шаг заключается в использовании классов эквивалентности для построения тестов. Этот процесс включает в себя:
- Назначение каждому классу эквивалентности уникального номера.
- Проектирование новых тестов, каждый из которых покрывает как можно большее число непокрытых правильных классов эквивалентности, до тех пор пока все правильные класс эквивалентности не будут покрыты (только не общими) тестами.
- Запись тестов, каждый из которых покрывает один и только один из непокрытых неправильных классов эквивалентности, до тех пор пока всех неправильные классы эквивалентности не будут покрыты тестами.
Причина покрытия неправильных классов эквивалентности индивидуальными тестами состоит в том, что определённые проверки с ошибочными входами скрывают или заменяют другие проверки с ошибочными входами. Например спецификации устанавливает "тип книги при поиске (ВЫЧИСЛИТЕЛЬНАЯ ТЕХНИКА, ПРОГРАММИРОВАНИЕ или ОБЩИЙ") и количество (1-9999)". Тогда тест
XYZ 0
отображает два ошибочных условия (неправильный тип книги и количество) и, вероятно, не будет осуществлять проверку количества, так как программа может ответить: "XYZ - НЕСУЩЕСТВУЮЩИЙ ТИП КНИГИ" и не проверять остальную часть входных данных.
Пример
Предположим, что при разработке компилятора для подмножества языка Фортран требуется протестировать синтаксическую проверку оператора DIMENSION. Спецификация приведена ниже. (Этот оператор не является полным оператором DIMENSION Фортрана; спецификация была значительно сокращена, что позволило сделать ее "учебным примером". Не следует думать, что тестирование реальных программ так же легко, как в примерах данной книги.) В спецификации элементы, написанные латинскими буквами, обозначают синтаксические единицы, которые в реальных операторах должны быть заменены соответствующими значениями, в квадратные скобки заключены необязательные элементы, многоточие показыает, что предшествующий ему элемент может быть повторен подряд несколько раз.
Оператор DIMENSION используется для определения массивов. Форма оператора DIMENSION:
DIMENSION ad[,ad]...,
где ad есть описатель массива в форме
n(d[,d]...),
n - символическое имя массива, а d - индекс массива. Символические имена могут содержать от одного до шести символов - букв или цифр, причем первой должна быть буква. Допускается от одного до семи индекса. Форма индекса
[lb:]ub,
где lb и ub задают нижнюю и верхнюю граничны индекса массива.
Граница может быть либо константой, принимающей значения от -65534 до 65535, либо целой переменной (без индексов). Если lb не определена, то предполагаетя, что она равна единице. Значение ub должно быть больше или равно lb. Если lb опрееделена, то она может иметь отрицательное, нулевое или положительное значение. Как и все операторы, оператор DIMENSION может быть продолжен на нескольких строках. (Конец спецификации.)
Первый шаг заключается в том, чтобы идентифицировать входные условия и по ним определить классы эквивалентности (таблица 4.1). Классы эквивалентности в таблице обозначены числами.
Входные условия Правильные классы эквивалентности Неправильные классы эквивалентности Число описателей массивов один (1), >
одного (2)ни одного (3) Длина имени массива 1-6 (4) 0 (5), >
6 (6)Имя массива имеет в своем составе буквы (7) и цифры (8) содержит что-то еще (9) Имя массива начинается с буквы да (10) нет (11) Число индексов 1-7 (12) 0 (13), >
7 (14)Верхняя граница константа (15), целая переменная (16) имя элемента массива (17), что-то иное (18) Имя целой переменной имеет в своем составе буквы (19), и цифры (20) состоит из чего-то еще (21) Целая переменная начинается с буквы да (22) нет (23) Константа -65534-65535 (24) < -65534 (25), > 65535 (26) Нижняя граница определена да (27), нет (28) Верхняя граница по отношению к нижней границе больше (29), равна (30) меньше (31) Значение нижней границы отрицательное (32), нуль (33), > 0 (34) Нижняя граница константа (35), целая переменная (36) имя элемента массива (37), что-то иное (38) Оператор расположен на нескольких строках да (39), нет (40) ... Следующий шаг - построение теста, покрывающего один или более правильных классов эквивалентности. Например, тест
DIMENSION A(2)
покрывает классы 1, 4, 7, 10, 12, 15, 24, 28, 29 и 40. Далее определяются один или более тестов, покрывающих оставшиеся правильные классы эквивалентности. Так, тест
DIMENSION A12345(I,9,J4XXXX,65535,1,KLM, X 100), BBB (-65534:100,0:1000,10:10,1;65535)
покрывает оставшиеся классы. Перечислим неправильные классы эквивалентности и соответствующие им тесты:
(3): DIMENSION (5): DIMENSION (10) (6): DIMENSION A234567(2) (9): DIMENSION A.1(2) (11): DIMENSION 1A(10) (13): DIMENSION B (14): DIMENSION B(4,4,4,4,4,4,4,4) (17): DIMENSION B(4,A(2)) (18): DIMENSION B(4,,7) (21): DIMENSION C(I.,10) (23): DIMENSION C(10,1J) (25): DIMENSION D(-65535:1) (26): DIMENSION D(65536) (31): DIMENSION D(4:3) (37): DIMENSION D(A(2):4) (38): DIMENSION D(.:4)
Эти классы эквивалентности покрываются 18 тестами. Читатель может при желании сравнить данные тесты с набором тестов, полученным каким-либо специальным методом.
Хотя эквивалентное разбиение значение лучше случайного выбора тестов, оно все же имеет недостатки (то есть пропускает определенные типы высокоэффективных тестов). Следующие два метода - аналаз граничных значений и использование функциональных диаграмм (диаграммм причинно-следственный связей cause-effect graphing) - свободны от многих недостатков, присущих эквивалентному разбиению.
АНАЛИЗ ГРАНИЧНЫХ ЗНАЧЕНИЙ
Как показывает опыт, тесты, исследующие граничные условия, приносят большую пользу, чем тесты, которые их не исследуют. Граничные условия - это ситуации, возникающие непосредственно на, выше или ниже границ входных и выходных классов эквивалентности. Анализ граничных значений отличается от эквивалентного разбиения в двух отношениях:
- Выбор любого элемента в классе эквивалентности в качестве представительного при анализе граничных значений осуществляется таким образом, чтобы проверить тестом каждую границу этого класса.
- При разработке тестов рассматривают не только входные условия (пространство входов), но и пространство результатов (то есть выходные классы эквивалентности).
Трудно описать "кухню" анализа граничных значений, так как это требует определенной степени творчества и специализации в рассматриваемой проблеме. (Следовательно, анализ граничных значений, как и многие другие аспекты тестирования, в значительной мере основываются на способностях человеческого интеллекта.) Тем не менее приведем несколько общих правил этого метода.
- Построить тесты для границ области и тесты с неправильными входными данными для ситуаций незначительного выхода за границы области, если вхоное условие описывает область значений. Например, если правильная область входных значений есть -1.0 - +1.0, то написать тесты для ситуаций -1.0, 1.0, -1,001 и 1,001.
- Построить тесты для минимального и максимального значений условий и тесты, большие и меньшие этих значений, если входное условие удовлетворяет дискретному ряду значений. Например, если входной файл может содержать от 1 до 255 записей, то получить тесты для 0, 1, 255 и 256 записей.
- Использовать правило 1 для каждого выходного условия. Например, если программа вычисляет ежемесячный расход и если минимум расхода составляет 0.00 дол., а максимум - 1165.25 дол., то построить тесты, которые вызывают расходы с 0.00 дол. до 1165.25 дол. Кроме того, построить, если это возможно, тесты, которые вызывают отрицательный расход и расходе больше 1165.25 дол. Заметим, что важно проверить границы пространства результатов, поскольку не всегда границы входных областей представляют такой же набор условий, как и границы выходных областей (например, при рассмотрении подпрограммы вычисления синуса). Не всегда также можно получить результат вне выходной области, но тем не менее стоит рассмотреть эту возможность.
- Использовать правило 2 для каждого выходного условия. Например, если система информационного поиска отображает на экране терминала наиболее релевантные рефераты в зависимости от входного запроса, но никак не более четырех рефератов, то построить тесты, такие, чтобы программа отображала нуль, один и четыре реферата, и тест, который мог бы вызвать выполнение программы с ошибочным отображением пяти рефератов.
- Если вход или выход программы есть упорядоченное множество (например, последовательный файл, линейный список, таблица), то сосредоточить внимание на первом и последнем элементах этого множества.
- Попробовать свои силы в поиске других граничных условий.
Чтобы проиллюстрировать необходимо анализа граничных значений, можно использовать программу анализа треугольника, приведенную в главе 1. Для задания треугольника входные значения должны быть целыми положительными числами, и сумма любых двух из них должна быть больше третьего. Если определены эквивалентные разбиения, то целесообразно определить одно разбиение, в котором это условие выполняется, и другое, в котором сумма двух целых не больше третьего. Следовательно, двумя возможными тестами являются 3-4-5 и 1-2-4. Тем не менее здесь есть вероятность пропуска ошибки. Иными словами, если выражение в программе было закодировано как
A + B >=C
вместоA + B > C
, то программа ошибочно сообщала бы нам, что числа 1-2-3 представляют правильный равносторонний треугольник. Таким образом, существенное различие между анализом граничных значений и эквивалентным разбиением заключается в том, что анализ граничных значений исследует ситуации, возникающие на и вблизи границ эквивалентных разбиенией.В качестве примера применения метода анализа граничный значений рассмотрим следующую спецификацию программы.
MTEST есть программа, которая сортирует различную информацию об экзаменах. Входом программы является файл, названный OCR, который содержит 80-символьные записи. Первая запись представляет название; ее содержание используется как заголовок каждого выходного ответа. Следующее множество записей описывает правильные ответы на экзамене. Каждая запись этого множества содержит "2" в качестве последнего символа. В первой записи в колонках 1-3 задается число ответов (оно принимает значения от 1 до 999). Колонки 10-59 включают сведения о правильных ответах на вопросы с номерами 1-50 (любой символ воспринимается как ответ). Последующие записи содержат в колонках 10-59 свежения о правильных ответа на вопросы с номерами 51-100, 101-150 и так далее, Третье множество записей описывает ответы каждого студента; любая запись этого набора имеет число "3" в восьмидесятой колонке. Для каждого студента первая запись в колонках 1-9 содержит его имя или номер (любые символы); в колонках 10-59 помещены сведения о результатах ответов студентов на вопросы с номерами 1-50. Если в тесте предусмотрено более чем 50 вопросов, то последующие записи для студента описывают ответы 51-100, 101-150 и так даллее в колонках 10-59. Максимальное число студентов - 200. Форматы входных записей показаны на рисунке 4.4. Выходными записями являются: 1) ответ, упорядоченные в ликсикографическом порядке идентификаторов студентов и показывающий качество ответов каждого студента (процентр правильных ответов) и его ранг; 2) аналогичный отчет, но упорядоченный по качеству; 3) отчет, показывающий среднее значение, медиану и среднее квадратическое отклонение качества ответов; 4) отчет, упорядоченный по номерам вопросов и показывающий процент студентов, отвечающих правильно на каждый вопрос. (Конец спецификации.)
Начнем методичное чтение спецификации, выявляя входные условия. Первое граничное входное условие есть пустой входной файл. Второе граничное условие - карта (запись) названия; граничными условиями являются отсутствие карты названия, самое короткое и самое длинное название. Следующими входными условиями служат наличие записей о правильных ответах и наличие поля числа вопросов в первой записи ответов. 1-999 не является классов эквивалентности для числа вопросов, так как для каждого подмножества из 50 записей может иметь место что-либо специфическое (то есть необходимо много записей). Примелемое разбиение вопросов на классы эквивалентности представляет разбиение на два подмножества: 1-50 и 51-999. Следовательно: необходимый тесты, где поле числа вопросов принимает значения 0, 1, 50, 51 и 999. Эти тесты покрывают большинство граничных условий для записей о правильных ответа: однако, существуют три более интересные ситуации - отсутствие записей об ответах, наличие записей об ответах типа "много ответов на один вопрос" и наличие записей об ответах типа "мало ответов на один вопрос" (например, число вопросов - 60, и имеется три записи об ответах в первом случае и одна запись об ответах во втором). Таким образом, определены следующие тесты:
- Пустой входной файл.
- Отсутствует запись названия.
- Название длиной в один символ.
- Название длиной в 80 символов.
- Экзамен из одного вопроса.
- Экзамен из 50 вопросов.
- Экзамен из 51 вопроса.
- Экзамен из 999 вопросов.
- 0 вопросов на экзамене.
- После числа вопросов имеет нечисловые значения.
- После записи названия нет записей о правильных ответах.
- Имеются записи типа "много правильных ответов на один вопрос".
- Имеются записи типа "мало правильных ответов на один вопрос".
Следующие входные условия относятся к ответам студентов. Тестами граничных значений в этом случае, по-видимому, должны быть:
- 0 студентов
- 1 студент
- 200 студентов.
- 201 студент.
- Есть одна запись об ответе студента, носуществует две записи о правильных ответах.
- Запись об ответе вышеупомянутого студента первая в файле.
- Запись об ответе вышеупомянутого студента последняя в файле.
- Есть две записи об ответах студента, но существует только одна запись о правильном ответе.
- Запись об ответах вышеупомянутого студента первая в файле.
- Записьмо об ответах вышеупомянутого студента последняя в файле.
Можно также получить набор тестов для проверки выходных границ, хотя некоторые из выходных границ (например, пустой отчет 1) покрывается приведенными тестами. Граничными условиями для отчетов 1 и 2 являются: 0 студентов (так же, как тест 14); 1 студент (так же, как тест 15); 200 студентов (так же как тест 16).
- Оценки качества ответов всех студентов одинаковы.
- Оценки качества ответов всех студентов различны.
- Оценки качества ответов некоторых, но не всех студентов одинаковы (для проверки правильности вычисления рангов).
- Студент получает оценку качества ответа 0.
- Студент получает оценку качества ответа 100.
- Студент имеет идентификатор наименьшей возможной длины (для проверки правильности упорядочения).
- Студент имеет идентификатор наибольшей возможной длины.
- Число студентов таково, что отчет имеет размер, несколько больший одной страниц (для того чтобы посмотреть случай печати на другой странице).
- Число студентов такого, что отчет располагается на одной странице. Граничные условия отчета 3 (среднее значение, медиана, среднее квадратическое отклонение):
- Среднее значение максимально (качество ответов всех студентов наивысшее).
- Среднее значение равно 0 (качество ответов всех студентов равно 0).
- Среднее квадратическое отклонение равно своему максимуму (один студент поулчает оценку 0, а другой - 100).
- Среднее квадратическое отклонение равно 0 (все студенты получают одну и ту же оценку).
Тесты 33 и 34 покрывают и границы медианы. Другой полезный тест описывает ситуацию, где существует 0 студентов (проверка деления на 0 при вычислении математического ожидания), но он идентичен тесту 14.
Проверка отчета 4 дает следующие тесты граничных значений:
- Все студенты отвечают правильно на первый вопрос.
- Все студенты неправильно отвечают на первый вопрос.
- Все студенты правильно отвечают на последний вопрос.
- Все студенты отвечают на последний вопрос неправильно.
- Число вопросов таково, что размер отчета несколько больше одной страницы.
- Число вопросов такого, что отчет располагается на одной странице.
Опытный программист, вероятно, соглаится с той точкой зрения, что многие из этих 42 тестов позволяют выявить наличие общих ошибок, которые могут быть сделаны при разработке данной программы. Кроме того, брольшинство этих ошибок, вероятно, не было бы обнаружено, если бы использовался метод случайной генерации тестов или специальный метод генерации тестов. Анализ граничных значений, если он применен правильно, является одним из наиболее полезных мтеодов проектирования тестов. Однако он часто оказывается неэффективным из-за того, что внешне выглядит простым. Читатель должен понимать, что граничные условия могут быть едва уловимы и, следовательно, определение их связано с большими трудностями.
«Тестирование программного обеспечения. Фундаментальные концепции менеджмента бизнес-приложений», Сэм Канер, Джек Фолк и Енг Кек Нгуен, Москва, ДиаСофт, 2001. 97, 181, 191-192 страницы:
Простейшими граничными условиями являются числовые… Любой аспект работы программы, к которому применимы понятия больше или меньше, раньше или позже, первый или последний, короче или длиннее, обязательно должен быть проверен на границах диапазона… на границах порой случаются самые неожиданные отклонения...
Весь продукт тестировать не нужно, достаточно выбрать пять полей ввода данных — они обычно имеются в любой программе… Для каждого поля ввода данных выполните следующее:
- Проанализируйте значения, которые в него можно вводить. Сгруппируйте их в классы.
- Проанализируйте возможные граничные условия. Их можно описать, исходя из определений классов, но возможно, что в ходе этого анализа добавятся и новые классы значений.
- Нарисуйте таблицу, в которой перечислите все классы значений для каждого поля ввода и все интересные тестовые примеры (граничные и другие особые значения). Пример такой таблицы приведен на рисунке 7.1. Если у вас будет плохо получаться, прочитайте раздел главы 12 «Таблицы граничных значений».
- Протестируйте программу, используя записанные значения (а если их слишком много, то некоторое их подмножество). Протестировать программу, означает не только запустить ее, ввести данные и посмотреть, не произойдет ли сбой, — важно, чтобы программа правильно использовала введенные данные. Получаются ли, например, при печати указанные пользователем отступы? Обязательно продумайте тестовую процедуру, в которой программа использует введенную вами информацию
Для каждого класса эквивалентности достаточно провести один-два теста. И лучшими из них будут те, которые проверяют значения, лежащие на границах класса...
О вопросах, освещаемых в этой главе, подробно рассказывается у Майерса (Myers, 1979) — особенно хорошо он пишет о классах и граничных условиях...
Необходимо протестировать каждую границу класса эквивалентности, причем с обеих сторон… Вот ряд примеров…
- Если допустимые значения от 1 до 99, для тестирования допустимых данных можно выбрать 1 и 99, а для тестирования недопустимых 0 и 100.
- Если программа выписывает чеки на суммы от $1 до $99, то стоит попробовать выписать чек на отрицательную сумму, на $0, на $1000.
- Если программа рисует линии длиной от одной точки до 4 сантиметров, нарисуйте одну точку и линию длиной ровно 4 сантиметра. ПУсть программа также попробует нарисовать линию нулевой длины.
- Если сумма входных значений должна равняться 180, попробуйте ввести значения, дающие в сумме 179, 180 и 181.
- Если программа ожидает заглавную английскую букву, введите A и Z. Проверьте также символ @, поскольку его код предшествует коду символа A, и символ ], код которого следует за кодом символа Z. Кроме того, проверьте символы a и z.
- Если сумма входных значений должна равняться 180, попробуйте ввести значения, дающие в сумме 179, 180 и 181.
- Если программа получает определенное количество входных данных, попробуйте ввести в точности необходимое количество, на единицу меньшее и на единицу большее.
- Если программа принимает ответы B, C и D, попробуйте ввести A и E.
- Попробуйте отправить на печать файл непосредственно перед и сразу после того, как принтер напечатает еще чье-либо задание.
- После чтения и записи файла на диск проверьте его первый и последний символы.
Анализируя границы диапазонов значений, очень важно учесть все возможные выходные данные. Проанализируйте каждый элемент распечатки или изображения на экране. Каковы допустимые перечни или максимальные и минимальные значения каждого печатаемого параметра? Можно ли заставить программу сформировать данные, выходящие за эти границы и как это сделать?
«Lessons Learned in Software Testing: A Context-Driven Approach», Сэм Канер, Джеймс Маркус Бах, Брет Петтичорд, переводчик Максим Захаров. Wiley, 2001 год:
Тестирование граничных значений
Класс эквивалентности - это набор переменных. Если вы можете отразить их на числовой оси, то граничными значениями будут наибольшие и наименьшие значения класса. В тестировании граничных значений вы тестируете их, а также те граничные значения близлежащих классов, которые лишь ненамного меньше, чем наименьшее значение вашего класса и ненамного больше, чем наибольшее значение вашего класса. Рассмотрим поле ввода, принимающее целые значения от 10 до 50. Значения, представляющие интерес, это: 10(меньшее значение), 9(наибольшее неподходящее значение), 50(наибольшее), 51(наименьшее неподходящее).
"Быстрое тестирование", Роберт Калбертсон, Крис Браун, Гэри Кобб. Издательский дом "Вильямс", 2002. 75, 108-109, 214-215 страница:
Разбиение на классы эквивалентности. Разбиение на классы эквивалентности пред ставляет собой технологию проектирования тестов, ориентированную на снижение общего числа тестов, необходимых для подтверждения корректности функциональ ных возможностей программы. Основная идея, стоящая за разбиением на классы эк вивалентности, заключается в том, чтобы разбить область ввода программы на клас сы данных. Если проектировать тесты для каждого класса данных, но не для каждого члена класса, то общее количество требуемых тестов уменьшается.
В качестве примера рассмотрим программу отображения почтовых индексов, ко торая рассматривалась ранее в главе. Предположим, что когда пользователь вводит пятизначный почтовый индекс и общую массу отправляемого груза в унциях, про грамма возвращает стоимость доставки пакета. Областью ввода для этой программы являются почтовые индексы и масса брутто отправляемого груза. Область ввода поч тового кода может быть разбита на класс допустимых вводов и класс недопустимых вводов следующим образом:
- Допустимыми вводами являются все пятизначные наборы цифровых символов, образующих рабочий почтовый код
- Недопустимыми вводами являются:
- Наборы цифровых символов, содержащие менее пяти символов
- Наборы цифровых символов, содержащие более пяти символов
- Наборы из пяти символов, не являющиеся рабочим почтовым кодом
- Наборы из нецифровых символов.
Аналогичное разбиение может быть построено и для массы брутто отправляемого груза. Например, требуется программа, работающая только с грузами, масса которых находится в диапазоне от 1 до 100 унций. В этом случае числовые значения, попа дающие в диапазон от 1 до 100, включая и конечные точки, являются допустимыми. Все значения меньше 1 и больше 100, отрицательные значения и нецифровые значе ния образуют недопустимые классы ввода.
Нужно спроектировать такие тесты, которые выполняют проверку, по меньшей мере, одного представителя каждого допустимого класса ввода и, по меньшей мере, одного представителя недопустимого класса ввода. В результате тестирования с при менением допустимых вводов должны быть получены однозначно определенные и ожидаемые результаты. Для почтового кода 78723 и массы в 20 унций ожидается по лучить конкретное значение стоимости, и это значение должно быть определено в функциональных требованиях. В случае ввода недопустимых данных должно быть получено соответствующее сообщение об ошибке, если оно определено в техниче ских требованиях и спецификациях. При вводе недопустимых данных программа, по меньшей мере, не должна завершаться аварийно, вызывать искажение данных или вести себя непредсказуемым образом.
Более подробное обсуждение разбиения на классы эквивалентности можно найти в главе 10 "Технологии динамического тестирования и советы", а также в:
- Myers, Glen. (1979). The Art of Software Testing. New York: Wiley.
- Kaner, Cem, Jack Falk, and Hung Quoc Nguyen. (1999). Testing Computer Software (2nd ed.). New York: Wiley.
- Pressman, Roger. (1997). Software Engineering: A Practitioner's Approach (4th ed.). New York: McGraw-Hill.
- Kit, Edward. (1995). Software Testing in the Real World: Improving the Process. Reading, MA: Addison-Wesley.
- Fewster, Mark, and Dorothy Graham. (1999). Software Test Automation. Reading, MA: Addi son-Wesley.
Анализ граничных значений. Анализ граничных значений представляет собой тех нологию проектирования тестов, которая является дополнением разбиения на клас сы -эквивалентности. Вместо того чтобы выбирать некоторый конкретный элемент класса эквивалентности, анализ граничных значений предлагает проектировщику теста выбрать элементы, которые находятся "на границе" класса. Экспериментально было доказано, что дефекты имеют тенденцию концентрироваться на границе облас ти ввода, а не в ее центре. Не особенно ясно, почему так получается, это всего лишь установленный факт.
Например, в случае программы, которая для почтового индекса и веса отправляе мого груза вычисляет стоимость доставки, анализ граничных значений позволяет применять в качестве тестовых значений минимальное и максимальное значение ве са (1 унция и 100 унций), а также ближайшее значение, меньшее минимально допус тимого (0 унций), и ближайшее значение, большее максимально допустимого (101 унция). Эти значения позволяют проверить границы диапазона допустимых значе ний, а также значения, выходящие за пределы этого диапазона. Более подробную информацию по анализу граничных значений можно найти в главе 10 "Технологии динамического тестирования и советы", а также в
- Myers, Glen. (1979). The Art of Software Testing. New York: Wiley.
- Kaner, Cem, Jack Falk, and Hung Quoc Nguyen. (1999). Testing Computer Software (2nd ed.). New York: Wiley.
- Pressman, Roger. (1997). Software Engineering: A Practitioner's Approach (4th ed.). New York: McGraw-Hill.
- Fewster, Mark, and Dorothy Graham. (1999). Software Test Automation. Reading, MA: Addi son-Wesley.
Разделение по классам эквивалентности
Принадлежность двух элементов данных к одному и тому же классу эквивалентности просто означает, что с каждым из них функция выполняет одни и те же операции. Принадлежность двух элементов данных к различным классам эквивалентности оз начает, что существует, по меньшей мере, одна строка кода, требуемая для обработки одного элемента данных, которая не будет использоваться при обработке другого элемента данных. Часто данные, принадлежащие к одному из двух классов эквива лентности, называют правильными данными, а данные второго класса эквивалентно сти — неправильными данными для данной функции. Ветви кода, которые используются для обработки правильных данных, называются удачными ветвями, в то время как вет ви, выполняемые функцией при обработке неправильных данных, называются не удачными ветвями. В проектной документации для большинства функций определены правильные и неправильные входные данные. Для определения классов эквивалентно сти данных для каждой функции тестировщики должны прочесть проектную доку ментацию. Если эта информация отсутствует в проектной документации, тестиров- щику придется применить функциональный анализ и восстановить информацию о классах эквивалентности снизу-вверх. В некоторых случаях в проектной документа ции может использоваться также термин допустимых и недопустимых данных для дай ной функции. Операции тестирования во время ввода неправильных данных доста точно точно называются отрицательным тестированием. Неправильные данные вы бираются с тем, чтобы убедиться в наличии в каждой функции обработчиков исклю чений, выполняющих обработку неправильных данных. Отрицательное тестирова ние не ограничивается одним лишь выполнением операций тестирования для случая неправильных данных (обратитесь к разделу, посвященному отрицательному тести рованию, далее в этой главе).
Одна из принципиальных отличительных черт специалиста по тестированию, применяющего технологии быстрого тестирования, состоит в том, что при оценке вероятности наличия скрытых ошибок, которые могут препятствовать эффективному использованию конечной программы, он всегда учитывает широту и степень по крытия тестирования. Чтобы гарантировать тестирование как удачных, так и не удачных ветвей внутри каждой функции, тестировщик должен уделять пристальное внимание классам эквивалентности входных данных функций.
Анализ граничных значений
Весьма перспективной областью для поиска ошибок являются границы классов экви валентности функции. Как правило, анализ, который ведет к определению классов эквивалентности, определяет и эти границы. Включение нескольких пограничных значений в тестовые случаи для данной функции поможет проверить удовлетворение ожиданий (требований) пользователя. Кратко рассмотрим причины ошибок разра ботчиков при кодировании граничных значений. Причины появления в программ ных продуктах ошибок, связанных с граничными значениями, достаточно легко по нять, анализируя количество преобразований, которые выполняются с момента раз работки требований до момента начала динамического тестирования. Прежде всего, все требования создаются на высоком уровне. Они содержат не слишком много под робностей. Как правило, на этапе рабочего проектирования (РП) проектировщики программного обеспечения добавляют в RTM так называемые производные требова ния, преобразуя исходные требования в подробные и точные с точки зрения вычислений.
В организациях, занимающихся быстрым тестированием, уже осознали важность этапа РП для команды тестирования. Если производные требования отсутствуют или разработаны неправильно, то персоналу, занятому кодированием или тестировани ем, в ходе планирования, соответственно, придется дополнять высокоуровневый проект архитектуры и исходные требования этими документально оформленными подробностями рабочего проекта, в том числе и определяющими поведение про граммы на границах классов эквивалентности. В качестве примера рассмотрим кон струкции IF. По прошествии ряда лет многие исследователи в области компьютерных наук отметили, что утверждения в конструкции IF — это те программные элементы, в которых ошибки встречаются наиболее часто. Решение об использовании условия "меньше чем" или "меньше или равно" в утвердительной части конструкции IF часто принимается на этапе РП. В противном случае отсутствие этих спецификаций долж но быть выявлено во время инспекций, выполняемых на этапе РП.
«Тестирование Дот Ком, или Пособие по жестокому обращению с багами в интернет-стартапах», Роман Савин, Москва, Дело, 2007. 195-202 страницы:
ЭКВИВАЛЕНТНЫЕ КЛАССЫ (equivalent classes)
Это суперполезная вещь, которой мы немедленно дадим определение: эквивалентный класс — это одно или больше значений ввода, к которым ПО применяет одинаковую логику.
Предположим, что наш книготорговый веб-сайт запускает новую кампанию "Больше тратишь — больше скидка". Вот табличка из спека.
Потраченная сумма, руб. Скидка, % 200 — 500 2 500 — 1000 3 1000 — 5000 4 5000 и более 5 Мы, конечно, сразу увидели 3 бага спека:
Баг1: Непонятно, по какой ставке рассчитывается скидка, если потрачены следующие суммы: ровно 500 руб., ровно 1000 руб., ровно 5000 руб., так как каждая из этих сумм находится не в одной, а в двух корзинах со скидками.
Баг 2: Что означает "Потраченная сумма"? Это количество дензнаков, выплаченных только за книги, или полная сумма к оплате, включая оплату книг и расходы на доставку?
Баг 3: Для полноты картины нужно дописать эквивалентный класс от 0 до 199,99, на значения которого никакая скидка не распространяется.
Что делаем? Правильно: идем к продюсеру. Извещаем о баге программиста. "Размораживаем" спек. Вносим в него изменения.
Вот перед нами уже отредактированная табличка:
Стоимость купленных книг, руб. Скидка, % 0—199,99 0 200,00 — 499,99 2 500,00 — 999,99 3 1000,00 — 4999,99 4 5000,00 и более 5 У нас получилось 5 эквивалентных классов:
Класс Стоимость Класс 1: 0—199,99 Класс 2: 200,00 — 499,99 Класс 3: 500,00 — 999,99 Класс 4: 1000,00 — 4999,99 Класс 5: 5000,00 и более Каждое значение внутри каждого класса является эквивалентным всем другим значениям этого класса. Почему? Потому что ко всем значениям класса должна применяться одинаковая логика кода. Например, при стоимости купленных книг и 1215,11 руб., и 1745,45 руб., и 2000 руб. (класс 4) полагается скидка 4%.
Составными частями класса являются:
- Значение или корзина значений ввода (например, от500,00 до 999,99) и
- Логика для вывода, т.е. ожидаемого результата (скидка 3% в случае с классом 3).
Польза раскладывания значений ввода на эквивалентные классы состоит в том, что мы отсеиваем огромное количество значений ввода, использовать которые для тестирования просто бессмысленно.
Отсев происходит путем применения знаний о тестировании пограничных значений.
ПОГРАНИЧНЫЕ ЗНАЧЕНИЯ (boundary values)
Все очень просто. Давайте представим себе наши эквивалентные классы из предыдущего примера:
Вертикальная пунктирная линия — это первое возможное значение класса (нижний предел). Вертикальная сплошная линия — это последнее возможное значение класса (верхний предел).
Пограничные значения — это конкретные предельные значения, образующие водораздел между эквивалентными классами.
Для каждого эквивалентного класса может быть лишь один из трех вариантов:
- а. Есть только нижний предел (класс 5).
- б. Есть нижний и верхний пределы (класс 2, класс 3, класс 4).
- в. Есть только верхний предел (не рассматриваемый в данном примере класс, который ограничен только сверху гипотети ческим отрицательным значением, непосредственно пред шествующим классу 1).
Пограничным тестированием (boundary testing) называется применение метода тестирования пограничных значений.
Вот полная версия метода тестирования пограничных значений.
- а. Сначала тестируется нижний предел данного класса (если он имеется).
б. Затем тестируется верхний предел данного класса (если он имеется).
в. Затем тестируется любое значение внутри данного класса.
- г. Затем тестируется верхний предел класса, непосредственно предшествующего данному классу (если предшествующий класс имеется).
- д. Затем тестируется нижний предел класса, непосредственно следующего за данным классом (если следующий класс имеется).
а, б, в являются позитивными тестами, г и д — негативными тестами.
Давайте же возьмем и протестируем эквивалентный класс 2. Суть тестирования заключается в том, чтобы удостовериться, что для покупок от 200,00 до 499,99 руб. (включительно) будет дана скидка 2%. Опустим шаги сценариев и поговорим только о данных для них. Следуем методике тестирования эквивалентного класса, нам нужно лишь пять вариантов данных:
- а. 200,00;
- б. 499,99;
- в. 315,11;
- г. 199,99;
- д. 500,00.
Почему нам хватило только 5 сценариев, мы поговорим через минуту.
А сейчас давайте посмотрим, сколько возможных вариантов только для позитивных тестов у нас потенциально есть для класса 2: 30 000 (по количеству копеек в 299,99 руб. плюс один случай, когда потрачено 200,00 руб.).
Наша методика позволила обойтись лишь 3 тестами (позитивные тесты: а, б, в), которыми мы по сути протестировали 30 000 значений. По-моему, выглядит впечатляюще.
Теперь о 5 сценариях, которых было достаточно для позитивного и негативного тестирования класса 2.
Представим себе схематично логику кода для решения вопроса о скидке для класса 2:
ЕСЛИ сумма > 200,00 И сумма < 499,99, ТО скидка = сумма /100 х 2.
Теперь рассмотрим, как каждый из наших тест-кейсов точечно бьет по возможным проблемам кода. Прошу особого внимания — ничего сложного нет, но много нюансов.
Тест-кейс Код с выделенной жирным шрифтом частью, которая проверяется данным тестом Возможная проблема кода, разоблачаемая тестом, и пример проблемы Ожидаемый результат а. Сначала тестируется нижний предел данного класса (если нижний предел имеется): 200 ЕСЛИ сумма > **200,00** И сумма < 499,99, ТО скидка = сумма/100 х 2
Ошибка в знаке равенства и/или сумме нижнего предела. Пример (знакравенства перед 200,00 пропущен): ЕСЛИ сумма > 200,00 И сумма < 499,99, ТО скидка = сумма/100 х 2
2% от 200 б. Затем тестируется верхний предел данного класса (если верхний предел имеется): 499,99 ЕСЛИ сумма > 200,00 И сумма < **499,99**, ТО скидка = сумма/100 х 2
Ошибка в знаке равенства и/или сумме верхнего предела. Пример (499,00 вместо 499,99): ЕСЛИ сумма > 200,00 И CVMMQ < 499,00, ТО скидка = сумма/100 х2
2% от 499,99 в. Затем тестируется любое значение внутри данного класса: 315,11 ЕСЛИ сумма > **200,00** И сумма < **499,99**, ТО скидка = сумма/100 х 2
Ошибка в знаках больше (>) и меньше (<). Пример (больше вместо меньше и меньше вместо больше): ЕСЛИ сумма < 200,00 И сумма > 499,00: ТО скидка = сумма/100 х 2
2% от 315,11 г. Затем тестируется верхний предел класса, непосредственно предшествующего данному классу (если предшествующий класс имеется): 199,99 ЕСЛИ сумма > **200,00** И сумма < 499,99, ТО скидка = сумма/100 х 2
Тонкий момент. Здесь мы проверяем две вещи: 1. Наличие скачка от верхнего предела предьщущего класса к нижнему пределу нашего класса. Это делается для следующей ситуации. Допустим, программист напечатал 100,00 вместо 200,00: ЕСЛИ сумма > 100,00 И сумма < 499,99, ТО скидка = сумма/100 х 2
. Если сделана такая ошибка, то она не будет обнаружена ни тестом а, ни тестом б, ни тестом е. 2. Логическое "И", так как если бы у нас было "ИЛИ":ЕСЛИ сумма > 200,00 ИЛИ сумма < 499,99, ТО скидка = сумма/100 х 2
, то к данному классу принадлежало бы любое в принципе возможное значениеСкидка не равна 2% от 199,99 д. Затем тестируется нижний предел класса, непосредственно следующего за данным классом (если следующий класс имеется): 500,00 ЕСЛИ сумма > 200,00 И сумма < 499,99, ТО скидка = сумма/100 х 2
1. Наличие скачка от верхнего предела нашего класса к нижнему пределу следующего за ним класса. Это делается для следующей ситуации. Допустим, программист напечатал 599,99 вместо 499,99: ЕСЛИ сумма > 200 И сумма < 599,99, ТО скидка = сумма/100 х 2
. Если сделана такая ошибка, то она не будет обнаружена ни тестом а, ни тестом б, ни тестом в, ни тестом г. 2. Проверяется логическое "И", так как если бы у нас было "ИЛИ":ЕСЛИ сумма > 200,00 ИЛИ сумма < 499,99, ТО скидка = сумма/100 х 2
, то к данному классу принадлежало бы любое в принципе возможное значениеСкидка не равна 2% от 500,0 Замечу, что для удобства в понимании мы производили тестирование класса 2 изолированно от его собратьев.
И теперь, поняв и разобравшись, давайте рассмотрим, как нам протестировать все эквивалентные классы данного спека:
Класс Значение Ожидаемая ставка скидки, % Класс 1 0
100,00
199,990 Класс 2 200,00
315,11
499,992 Класс 3 500,00
659,23
999,993 Класс 4 1000,00
3265,26
4999,994 Класс 5 5000,00
5075,005 Итого 14 тест-кейсов для тестирования всех возможных значений. Неплохо. Очень даже неплохо!
На сером фоне 5 значений ввода, которые мы использовачи для изолированного тестирования нашего любимого класса 2. Прошу отметить следующую вещь: теперь, когда мы тестируем класс 2 вместе с окружающими его собратьями, для класса 2 достаточно 3 тест-кейсов, так как случаи г. (199,99) и д. (500,00) покрываются при тестировании класса 1 и класса 3 соответственно.
Мы рассмотрели самый сложный вариант пограничного тестирования, когда мы проверяли эквивалентные классы, включающие множества значений. Зато теперь, пройдя огонь, воду и медные трубы, нам ничего не стоит разобраться в более простом случае, когда эквивалентный класс содержит только одно значение.
Пример Возьмем индекс, который должен быть равен 6 цифрам (Индекс_эл 005 из табл. 1, матричной раскладки поля "Индекс"). Применяем метод тестирования пограничных значений:
- а. 6
- б. 6
- в. 6
- г. 5
- д. 7
Таким образом, у нас есть:
- один позитивный тест 6 и
- два негативных теста 5 и 7.
Мы применяем метод
- как обособленно (тестирование скидок), так и
- в сочетании с другими методами генерирования и отбора тестов (использование пограничных значений на матрич ной раскладке поля "Индекс").
Идея о возможности обособленного или интегрированного применения, конечно, относится к каждому из методов генерирования и отбора тестов.
Это все о пограничном тестировании.
Важная мысль перед списком изученных нами вещей о подготовке к тестированию:
Не методы должны управлять вашей подготовкой, а вы должны управлять методами так, чтобы с их помощью создать именно те тест-кейсы, которые с высокой вероятностью могли бы найти баги. Для этого нужно в совершенстве владеть каждым из методов. И только практика может отточить ваши навыки. Практикуйтесь и помните о примере с шахматами, которым мы поставили себе мозги в начале нашей сегодняшней беседы.
"Тестирование программного обеспечения. Базовый курс", Святослав Куликов. Версия книги 1.2.1 от 02.08.2017, EPAM Systems. 231-236 страницы:
>
04.09.2016