Книга "A Practitioner's Guide to Software Test Design" Lee Copeland была опубликована в 2003 году.
С тех пор она надежно закрепилась в списке книг, которые обязательно должен прочитать любой тестировщик. Её стоит прочитать в оригинале. Читается очень приятно: язык не сложный, стиль легкий. По ходу книги автор слегка иронизирует над собой, своими учениками, читателями и в целом над сферой нашей деятельности.


Далее приводится не перевод, а скорее подробный конспект раздела “Техники тестирования методом черного ящика”, в котором содержится описание применения техник тест-дизайна.


Ко мне в руки книга попала по совету бывшего коллеги, за что ему отдельное спасибо.


To be most effective and efficient test case must be designed, not just slapped together.

Equivalence Class Testing
Boundary Value Testing
Decision Table Testing
Pairwise Testing
State-Transition Testing
Use Case Testing


Классы эквивалентности (Equivalence Class Testing)


Техника


  1. Определить классы эквивалентности.
  2. Создать тест-кейсы для каждого класса эквивалентности.

Классом эквивалентности называется набор данных, который запускает одни и те же модули и должен приводить к одним и тем же результатам.


Любые данные в рамках класса эквивалентны, это означает что если один тест-кейс в кассе эквивалентности обнаружил/не обнаружил дефект, то все остальные тест-кейсы внутри этого класса эквивалентности обнаружат/не обнаружат тот же самый дефект.


Альтернативный подход — использование классов эквивалентности не для входов, а для выходов. Разделить варианты выходов на классы эквивалентности, определить какие входные значения могут инициировать такие выходы. Преимущество в том, что проверяется каждый возможный вариант выхода. Недостаток в том, что внутри класса эквивалентности по выходу, может прятаться несколько классов эквивалентности по входу.


При наличии нескольких переменных:


  1. валидные классы нескольких переменных объединяются в один тест-кейс;
  2. невалидные классы тестируются отдельно.
    Let your designers and programmers know when they have helped you. They’ll appreciate the thought and may do in again.


Граничные значения (Boundary Value Testing)


Техника


  1. Определить классы эквивалентности
  2. Определить границы каждого класса эквивалентности
  3. Создать тест-кейсы для каждого граничного значения, выбирая по одной точке непосредственно на границе, выше и ниже границы.

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


Значения определяются типом. Если граница 5, то для поля, где вводятся целые числа тестируются точки 4 и 6, а для поля, где вводятся суммы в рублях и копейках тестируются точки 4,99 и 5,01.


При наличии нескольких переменных:


  1. минимальные значения валидных границ объединяются в один тест-кейс;
  2. максимальные значения валидных границ объединяются в другой тест-кейс;
  3. невалидные границы тестируются отдельно, как и в случае с невалидными классами.
    Boundary value testing focuses on the boundaries because that is where so many defects hide.


Таблица принятия решений (Decision Table Testing)


Техника


  1. Определить все условия
  2. Составить все возможные комбинации условий
  3. Убрать лишние комбинации. Удаляются те, в которых изменение значений никак не влияет на получаемый результат (Don’t care — DC)
  4. Определить действия
  5. Создать тест-кейсы для каждой комбинации

Таблица принятия решений — представляет связь составных условий и результирующих действий.


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


23=8 комбинаций
Rule 1
Rule 2
Rule 3
Rule 4
Rule 5
Rule 6
Rule 7
Rule 8
Conditions
Допустимый код акции
N
N
N
N
Y
Y
Y
Y
Допустимое количество
N
N
Y
Y
N
N
Y
Y
Достаточно средств
N
Y
N
Y
N
Y
N
Y
Actions
Купить
N
N
N
N
N
N
N
Y

Внимательно посмотрев на таблицу, можно заметить, что в правилах 1, 2, 3, 4, если код акции недопустимый, то проверка остальных условий не имеет смысла. Правила 5 и 6 могут быть объединены, т.к. условие проверки средств никак не влияет на результат. Условия, которые не оказывают влияние на результат помечаются как “DC”. Таблица преобразуется:


4 комбинации
Rule 1
Rule 2
Rule 3
Rule 4
Conditions
Допустимый код акции
N
Y
Y
Y
Допустимое количество
DC
N
Y
Y
Достаточно средств
DC
DC
N
Y
Actions
Купить
N
N
N
Y

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


Famous Software Tester Mick Jagger gives excellent advice regarding this “You can’t always get what you want, but if you try sometimes, you just might find, you get what you need.”


Попарное тестирование


Техника


  1. Определить параметры (variables)
  2. Определить количество значений для каждого параметра (choices for variable)
  3. Построить массив, содержащий колонки для каждого параметра и значения в колонках, которые содержать все сочетания значений этих параметров друг с другом.
  4. Сопоставить полученный ортогональный массив с целью тестирования.
  5. Построить тест-кейсы.

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


Если количество комбинаций значений переменных велико, не стоит пытаться протестировать все возможные комбинации, лучше сосредоточиться на тестировании всех пар значений переменных.
Два подхода попарного тестирования (pairwise testing): метод ортогонального массива (orthogonal arrays) и метод всех пар (allpair algorithm).


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


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


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


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


There is no underlying “software defect physics” that guarantees pairwise testing will be of benefit. There is only one way to know — try it.


Диаграмма переходов состояний


Техника


Состояние (State) — Условие в котором система ожидает одно или несколько событий.Состояние помнит что было получено на вход и определяет ответную реакцию, которая должна произойти. Это событие может быть приводить в новое состояние и/или инициировать новое действие. Состояние обычно отражает значение некоторой переменной в системе. Изображается в форме круга.


Переход (Transition) — Представляет переход из текущего состояния в новое, в результате выполнения какого-то действия. Изображается в виде стрелки.


Событие (Event) — Событие, ставшее причиной изменения состояния. Обычно событие поступает в систему из внешнего мира посредством некоторого интерфейса. Иногда это событие инициируется внутри самой системы например такие как срабатывание таймера, снижение ниже какого-то уровня. Считается, что событие происходит моментально. Событие может быть как независимым, так и связанным. Когда событие случается, система может изменить состояние или остаться в прежнем состоянии и/или инициировать действие. События могут иметь, связанные с ними параметры (номер карты, сумма на счете). Изображается как подпись к стрелке перехода.


Действие (Action) — Операция, инициированная в результате смены состояния. Зачастую это некоторый ответ системы. Помните, что действие происходит при переходе между состояниями. Состояния сами по себе статичны. Указывается через слеш в подписи к стрелке перехода после события.


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


Может использоваться, когда системе нужно знать предысторию или правильный порядок выполнения операций.


На основании Диаграммы перехода состояний составляется Таблица перехода состояний. Таблица содержит 4 колонки: текущее состояние, событие, действие, следующее состояние.


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


Может быть выбран один из 4 вариантов создания тест-кейсов:


  1. Создать наборы тест-кейсов так, чтобы все состояния были пройдены хотя бы по одному разу. В одном тест-кейсе может быть описан переход через несколько состояний. Это довольно слабый уровень тестового покрытия.
  2. Создать наборы тест-кейсов так, чтобы все события были инициированы хотя бы по одному разу. Тест-кейсы, которые покрывают все события в то же время покрывают и все состояния. Снова слабый уровень тестового покрытия.
  3. Создать наборы тест-кейсов так, чтобы все пути были пройдены хотя бы по одному разу. Такой способ хорош с точки зрения тестового покрытия, однако практически не осуществим. Если диаграмма имеет циклы, то количество возможных путей может оказаться бесконечным.
  4. Создать наборы тест-кейсов так, чтобы все переходы были выполнены хотя бы по одному разу. Этот способ обеспечивает хороший уровень тестового покрытия, поэтому рекомендуется использовать именно его.
    image
    Рекомендуемая стратегия создания тест-кейсов состоит в том, чтобы хотя бы по разу протестировать все переходы между состояниями. В высокорисковых системах, где требуется более надежное тестовое покрытие, возможно создавать тест-кейсы на каждый путь (цепочку переходов) между состояниями.
    And now for something completely different. Monty Python


Варианты использования (Use Case Testing)


Техника


Use case — это сценарии, описывающие то как actor (обычно человек, но может быть и другая система) пользуется системой для достижения определенной цели. Варианты использования описываются с точки зрения пользователя, а не системы. Внутренние работы по поддержанию работоспособности системы не являются частью варианта использования.


Хотя бы один тест-кейс должен проверять основной сценарий и хотя бы по одному кейсу должно приходится на альтернативные сценарии.


Рекомендации по созданию тест-кейсов на основе вариантов использования


  1. Начать с валидных данных и наиболее частых сценариев.
  2. Проверить граничные значения и невалидные значения (с использованием ранее рассмотренных техник).
  3. Редко используемые сценарии, крайне важные для системы (так называемая “Остановка ядерного реактора” Shut Down The Nuclear Reactor)
  4. Тесты на каждое ветку-альтернативу (Extension) каждого шага
  5. Попробовать выполнить операцию в непривычном порядке
  6. Извратить предусловие, если это действительно может произойти
  7. Если транзакция имеет циклы, запустите ее в цикле, и не один-два раза — будьте жестче
  8. Найти очень долгий и извилистый путь и пройдите по нему
  9. Если ожидается, что транзакция будет выполняться в логичном порядке, попробовать выполнить ее в обратном порядке (например заполнить поля не сверху вниз, а снизу вверх)
  10. Создать тесты на защиту от дурака

Шаблон описания вариантов использования


Use Case Component
Description
Use Case Number or Identifier
(Номер или идентификатор)
Уникальный идентификатор
Use Case Name
(Наименование)
В форме предложения, содержащего глагол в активной форме (что сделать?).
Например, Авторизоваться, Создать заказ
Goal in Context
(Цель и контекст)
Более детальное описание цели, если это необходимо.
Например, Создать заказ от имени организации.
Scope (Границы)
Корпорация (общий)|Система|Подсистема
Level (Уровень)
Общая|Частная|Подфункция
Primary Actor (Основной исполнитель
Роль или описание основного пользователя
Preconditions (Предусловия)
Состояние, в котором система должна находится до начала варианта использования
Success End Conditions (В случае успеха)
Состояние, в которое должна перейти система в случае удачного завершения варианта использования
Failed End Conditions (В случае провала)
Состояние, в которое должна перейти система в случае НЕудачного завершения варианта использования
Trigger (Условие срабатывания)
Действие, инициирующее запуск этого варианта использования
Main Success Scenario
(Основной сценарий)
Шаги и действия
Extensions (Дополнительные условия)

Условия, под действием которых в основных шагах сценария могут возникнуть альтернативные варианты.
Sub-Variations
Альтернативы
Шаги и действия. Варианты которые не связаны с основным потоком, но могут возникнуть. Описываются для шага.
Priority (Приоритет)
Критический
Response Time
Время, требуемое для выполнения этого кейса
Frequency
Частота использования
Channels to Primary Actor
Interactive|File|Database Интерактивно/Файл/База
Data Due
Расписание
Completeness Level
Степень завершенности
Open Issues
Зарегистрированные дефекты

If you don’t try strange things. you know the users will.

Комментарии (2)


  1. amarao
    07.08.2019 14:21
    -1

    а почему изобретают новое слово "класс эквивалентности", когда в CS в контексте типобезопасности (и анализа поведения приложений) уже давно устоялся термин "инвариант"?


    1. voleka Автор
      07.08.2019 19:29

      В тестировании "класс эквивалентности" — это устоявшееся понятие.
      У Ли Копланда используется термин Equivalence Class Testing «тестирование с помощью эквивалентных классов».
      В ISTQB это называется Equivalence Partitioning «эквивалентное разделение».