понедельник, 14 декабря 2015 г.

Сознательное проектирование: эквивалентность vs границы

Я не отрицаю спонтанность и озарение в тестировании. Вдохновение и интуицию.

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

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

При этом я:
- не всегда понимала что именно проверяю данным тестом
- часто выполняла несколько (или даже много) однотипных тестов

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

Теперь я считаю, что:
- тест-дизайнер должен четко понимать назначение каждого теста. Понимать, что конкретно каждый из них проверяет.
- не плодить однотипные тесты. Все знают как тестируются поля для ввода чисел. Берем минимальное число, максимальное, -1 у нижней границы, +1  у нижней, -1 и +1 у верхней. А потом мы еще берем пару чисел из середины диапазона.

Иногда, когда у меня заканчивается львовский фундук в шоколаде, я становлюсь злобным бендеровцем перфекционистом. И тогда я говорю себе: зачем несколько тестов с цифрами из середины диапазона?

Вы можете ответить? Зачем два, три теста с цифрами из середины диапазона? Что мы проверяем? Можно ли от них вообще отказаться?

Давайте посмотрим.

Поле для ввода чисел обычно имеет два класса эквивалентности: валидные значения и невалидные.

Валидные это:
  • >=min AND <=max.
  • другие, обусловленные логикой
Невалидные, это все остальное, они делятся на подклассы:
  • <min
  • >max
  • не числа (например слова)
  • числа неподдерживаемого формата (напр. дробные в поле для целых чисел)
  • пустое поле
  • другие, обусловленные логикой

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

В то же время техника граничных значений утверждает, что по статистике (которую я, кстати, никогда нигде не встречала, только упоминания о ней), на границах перехода между классами часто встречаются ошибки (во всяком случае чаще, чем в середине класса). Также программисты, которые тоже люди, иногда забывают обозначить в коде разницу между > и >= и наоборот. Именно поэтому границы классов нужно тестировать отдельно (или дополнительно) и количество тестов на одну границу = 3: сама граница, +1 шаг от нее вверх, -1 шаг от нее вниз.

Кто хоть пару раз работал с границами быстро понимает, что если это граница верхняя, то смысл имеет лишь пара: сама граница, +1 шаг вверх. Один тест можно отбросить. Соответственно для нижней границы: сама граница, -1 шаг вниз.  (напоминаю, мы рассматриваем пример - поле для ввода числа).

Ок, границы проверили.

Зачем брать из середины диапазона?  Середина диапазона - это валидный класс, из которого мы уже проверили два значения - сами границы. Если вы усердствуете и проверили еще шаг внутрь границ (вглубь валидного класса), то у вас уже четыре теста на один класс.

Так нужны ли еще тесты со значениями из середины?

Для проверки валидного класса из которого уже покрыто несколько значений - не нужны.

Тем не менее, большинство тестировщиков берут хотя бы одно значение из середины. И не могут объяснить почему. Ну, так, берем на всякий случай.

Я могу объяснить.

Потому что мы исходим из гипотезы, что "на границах класса эквивалентности вероятность бага больше" - т.е. что поведение на границах может отличаться от поведения в середине диапазона.

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

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

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

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

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

И еще.

Мы выполняем дополнительные однотипные тесты (в сумме - пять значений из одного класса) для того, чтобы побольше симулировать работу пользователя. Чтобы внести элемент случайности в работу с системой. Так мы повышаем вероятность случайно найти неожиданный баг.

Комментариев нет:

Отправить комментарий