четвер, 9 січня 2014 р.

Классы эквивалентности и Граничные значения

Пролог

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

Классы эквивалентности

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

Небольшой классический пример ( такой вы найдете везде где описываются классы эквивалентности):

Есть поле вода с допустимым диапазоном значений от 1 до 1000.
Довольно пугающей перспективой выглядит тестирование всего диапазона - 1000 тестов на допустимые значения(1, 2, 3...1000) + несметное количество тестов на недопустимые значения (-45, G, #, и т.д.).
На подобное тестирование у вас никогда не будет ни времени ни желания.
 - Чем же нам могут помочь тут классы эквивалентности?
Мы исходим из того что все допустимые значения должны влиять на наше поле ввода одинаково, и следовательно смело можем назвать все числа от 1 до 1000 эквивалентными в этом случае. С другой стороны все недопустимые значения ( 2000, Петя, !) должны также одинаково влиять на поле ввода, в идеале не должно быть возможности их ввести в это поле. Таким образом у нас теперь есть два класса эквивалентности:


  1. числа от 1 до 1000 (допустимые значения)
  2. числа от -∞ до 0, от 1001 до +∞, а также все остальные буквы и символы (этот класс, очевидно, можно разбить на три-четыре независимых)

Итого используя классы эквивалентности можно протестировать поле ввода минимумом из 5 тестов. Ввести 5, -11, 1345, Боба, $#@. Согласитесь, выглядит куда оптимистичнее :-)

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

Приведем еще один пример (не такой классический как предыдущий, но не менее полезный):

У нас есть система работы с файлами. В системе возможны четыре типа файлов А, В, С, D. Каждый файл может находиться в одном из пяти состояний: Created, Edited, Loaded, Saved, Deleted.

Файл типа А может быть удален только в состоянии Created;
Файл типа В может быть удален только в состоянии Edited;
Файл типа C может быть удален только в состоянии Loaded;
Ну а файл типа D можно удалить только в состоянии Saved.
Это громоздкое условие можно неплохо иллюстрирует следующая таблица:



File Type/State
Created Edited Loaded Saved Deleted
A
Y
N
N
N
N
B
N
Y
N
N
N
C
N
N
Y
N
N
D
N
N
N
Y
N

Где Y - файл может быть удален / N - файл нельзя удалить

Тестируя в лоб нам необходимо провести 20 тестов что бы проверить возможность удалить все типы файлов во всех состояниях. Попробуем использовать уже известную нам технику и вывести классы эквивалентности в этом случае.
Итак для каждого типа файла можно вывести по два класса эквивалентности: можно удалить файл / нельзя удалить файл.  Итого количество тестов мы сократим до 8ми по два для каждого типа файлов. Но пойдя дальше и узнав как реализован доступ к удалению файла удается узнать что разрешение/запрет несет ответственность один и тот же код программы мы можем сократить количество классов эквивалентности до двух (можно удалить / нельзя удалить). Кажется что двух тестов теперь достаточно для проверки возможности удалять файлы. Но всегда важно помнить что возможность удалять файлы является так сказать критической с точки зрения важности для системы и ее пользователя. По этому нам не следует сокращать тесты в которых мы проверяем возможность удалять файлы 4 теста. Но мы смело можем провести 1 тест в место 16 ти проверок на запрет удалять файлы. Итого 5 тестов в место 20.

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

Если же у вас достаточно времени на проведение 20ти тестов, то следует провести эти 20 тестов и спать спокойно. Жаль что времени почти всегда не хватает.

Граничные значения

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

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

Если говорить сухо то в случае граничных значений нам на каждой границе диапазона следует проверить по три значения: собственно граничное значение, значение перед границей и значение после границы. Давайте вспомним наш недавний пример с полем ввода - мы остановились на пяти тестах (5, -11, 1345, Боба, $#@) и двух главных классах эквивалентности. Отбросим буквенно-символьную часть второго диапазона так как она не имеет общих границ с допустимыми значениями. Если расписать все числовые значения то явно можно увидеть что на числовой прямой мы получим три диапазона и две границы:


 -∞ ... 0, 1, 2 .. 999, 1000, 1001 ... +∞


Граничными значениями как видно являются 1 и 1000. Поскольку эта техника подразумевает проверку не только граничного значения но и двух соседних то к нашему набору тестов прибавятся еще 6 проверок (0, 1, 2, 999, 1000, 1001).

Сами диапазон допустимых значений и особенно их границы за частую не так тривиальны как в нашем примере, но если вы можете их выделить и скомбинировать с классами эквивалентности то вы получите хорошее (качественное) покрытие тестами вашей функциональности.

Эпилог

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