Есть два типа системных аналитиков: те, кто на слова "Acceptance Criteria" кивают уверенно, и те, кто кивают с лицом человека, которому эти слова не приносит радости. А потом открываешь их спецификацию и понимаешь, что критерии приёмки там формулировал кто угодно, но только не человек, который собирается это реализовывать.
Если ты читал мою прошлую статью на Хабре про Gherkin, то уже знаешь, что синтаксис GWT - это не просто красивый способ писать тесты. Это способ фиксировать поведение системы в формате, который понятен и бизнесу, и тестированию и разработчику.
В этой статье 7 типовых конструкций Given / When / Then, которые:
покрывают различные распространенные кейсы
превращаются в понятные тест-кейсы
не разваливаются на проде
С примерами, пояснениями, подводными камнями и шаблонами. Это, конечно, не покрывает все возможные сценарии, но дает направление, в котором ты должен смотреть.
Можешь брать их и применять на своем проекте. Чтож… Щас выскажусь!
Позитивный сценарий: когда всё идёт по плану
Это тот случай, когда пользователь делает то, что мы от него ожидаем, и система ведёт себя правильно. То, ради чего вообще разрабатывается фича.
Его надо описывать всегда. Он нужен и разработчику (чтобы понимать, как вообще работает функционал), и тестировщику (для проверки happy path), и бизнесу (для верификации, что система делает то, что надо).
Если в документации нет позитивного сценария, вся реализация становится предположением.
Пример:
Given пользователь авторизован
When он открывает страницу профиля
Then отображаются его личные данные
Пояснение: это базовая проверка. Позитивный сценарий может быть один, а может быть несколько при условии, что если есть разные контексты (разные роли, состояния, типы данных).
Подводные камни:
Пропущен контекст (например, что пользователь авторизован или имеет нужную роль).
Then включает сразу кучу действий.
Позитивный сценарий вообще не описан.
Шаблон:
Given [корректное начальное состояние]
When [пользователь выполняет ожидаемое действие]
Then [получает логичный результат]
Совет: даже если сценарий кажется очевидным, то его лучше записать. Потому что на проде "и так понятно" может не заработать.
Негативный сценарий: если пользователь ошибся
Негативные сценарии фиксируют, как система реагирует на ошибочные действия пользователя. Это может быть пустое поле, некорректный формат, попытка нажать на кнопку, когда что-то не заполнено, и множество других кейсов.
Такие сценарии позволяют избежать ситуации, когда интерфейс “молчит”, а пользователь не понимает, что произошло.
Пример:
Given поле Email не заполнено
When пользователь нажимает Сохранить
Then система показывает сообщение: “Поле обязательно для заполнения”
Пояснение: Негативные сценарии отвечают на вопрос, что произойдёт, если пользователь сделает что-то не так. Это может быть случайный клик, невалидные данные, пустое поле или попытка обойти ограничения. Без этих сценариев система кажется надёжной только до первой неожиданной ситуации.
Подводные камни:
Описывают общую проверку: "проверить обязательные поля", а какие именно - не ясно.
Нет описания визуальной реакции: выделение поля, поп-ап, текст ошибки.
Ошибки валидации не разбиты по типам (пусто / не тот формат / значение вне диапазона).
Шаблон:
Given [ошибочное или неполное состояние данных]
When [пользователь выполняет действие]
Then [система сообщает об ошибке и не продолжает выполнение]
Совет: старайся фиксировать ошибки поштучно: отдельно кейс с пустым полем, отдельно с неверным форматом. Это делает поведение системы предсказуемым и тестируемым.
Роли и доступы: кто и что может
Если в системе есть несколько ролей, поведение должно зависеть от того, кто именно с ней работает. У одних - только просмотр, у других - редактирование, у третьих - права на удаление и управление. Все эти ограничения важно зафиксировать не на словах, а в конкретных сценариях. Это важно не только для безопасности, но и для логики приложения в целом.
Пример:
Given пользователь с ролью Оператор
When он открывает раздел управления пользователями
Then система отображает сообщение: “Доступ запрещён”
Пояснение: роли напрямую влияют на то, как система ведёт себя для разных пользователей. Один и тот же функционал может быть доступен одним, частично доступен другим и полностью скрыт от третьих. Всё зависит от контекста!
Подводные камни:
Кейс описан только для одной роли. А другие? Неизвестно.
Не описано, что именно увидит пользователь: заглушка, ошибка или редирект.
Нет негативных кейсов. Что будет, если человек с ограниченными правами попробует получить доступ напрямую?
Шаблон:
Given [пользователь с определённой ролью]
When [он пытается получить доступ к функциональности]
Then [система разрешает или запрещает действие и показывает соответствующее сообщение]
Совет: роли - это не косметика. Даже если у роли только права на чтение, стоит зафиксировать, что именно она может делать. Не оставляй это на интерпретацию! Система должна вести себя предсказуемо для каждой роли.
Бизнес-ограничения
Иногда фича вроде бы есть, но работать должна только при определённых условиях: если хватает денег, если заказ в нужном статусе, если пользователь что-то уже заполнил. Такие правила не про интерфейс, а про бизнес-логику. Это особенно актуально в финтехе, логистике, подписках и маркетплейсах.
Пример:
Given на балансе пользователя 0 руб.
When он пытается оплатить подписку
Then кнопка Оплатить неактивна и выводится сообщение: “Недостаточно средств”
Пояснение: такие сценарии описывают условия, при которых система разрешает или блокирует действия. Они привязаны к данным, которые есть в системе. Если это не описать, то получится фича, которая иногда работает, иногда нет и никто не понимает, почему.
Подводные камни:
Условие упоминается в тексте, но в кейсе его нет. В итоге его не реализуют или трактуют по-своему.
Пропущены граничные значения. Что если сумма баланса равна стоимости? Можно? Нельзя?
Нет текста сообщения об ограничении, хотя это влияет и на поведение, и на пользовательский опыт и на тест-кейсы.
Шаблон:
Given [недостаточное или пограничное значение бизнес-данных] When [пользователь пытается выполнить действие] Then [система блокирует действие и объясняет причину]
Совет: не пиши абстрактно. Если у фичи есть условия, то фиксируй их явно: с числом, статусом, флагом. Формулировки вроде “если пользователь может” или “если хватает” - не работают. Каждый поймёт их по-своему. Чем точнее кейс, тем меньше шансов, что разработка и тестирование пойдут в разные стороны.
Интеграции: работа с внешними системами
Если система зависит от внешнего сервиса надо описывать не только успешный сценарий, но и поведение при сбоях, таймаутах и неожиданных ответах. Это особенно важно для сценариев, где результат зависит не от нашего кода, а от чужой инфраструктуры.
“Что делать, если сервис вернул 500?”, “А если пришёл пустой ответ?”, “А если вообще не ответил?” - и каждый решит по-своему.
Пример:
Given внешний сервис оплаты недоступен
When пользователь нажимает Оплатить
Then отображается сообщение: “Платёж временно невозможен”
Пояснение: интеграции - это всегда зона риска. Система должна чётко уметь различать: сервис ответил, ответил с ошибкой, не ответил вообще. И во всех случаях должно быть понятно, что происходит для пользователя.
Подводные камни:
Не описано поведение при ошибке или недоступности сервиса.
Пользователь получает нейтральный или технический текст вместо нормального сообщения.
Шаблон:
Given [внешний сервис вернул ошибку или не ответил]
When [система отправляет запрос]
Then [пользователь получает понятное сообщение, а ошибка фиксируется в логах]
Совет: в интеграционных сценариях важно описывать не только успех, но и сбои: недоступность сервиса, таймауты, неожиданные ответы. Что увидит пользователь? Что попадёт в лог? Какие шаги выполняются при отказе? Это делает систему предсказуемой.
Асинхронные процессы: когда нужно подождать
Если действие не даёт результат сразу, то нужно объяснить, что происходит в это время. Загрузка файла, генерация отчёта, проверка данных - всё это асинхронные процессы. Они могут занимать секунды или минуты. И пользователь должен понимать, что система что-то делает, а не зависла.
Пример:
Given файл загружен, но ещё обрабатывается
When пользователь открывает его карточку
Then отображается статус “В обработке”, без кнопки скачивания
Пояснение: асинхронные процессы часто игнорируют. “Ну, он же потом появится”. Но как? Через сколько? Можно ли перезагрузить страницу? Такие моменты нужно проговаривать и для пользователя, и для бекенда и для фронта.
Подводные камни:
Нет переходного статуса, система выглядит “пустой” или “сломанной”.
Пользователь может нажимать кнопки, пока процесс не завершён.
Не описано, как и когда появляется результат, можно ли обновить вручную.
Шаблон:
Given [процесс в состоянии ожидания или обработки]
When [пользователь взаимодействует с ним]
Then [интерфейс отображает статус и ограничивает действия до завершения]
Совет: опиши промежуточные состояния. Даже если результат появится “потом”, то это “потом” должно быть видно, понятно и контролируемо. Пользователь не должен гадать, работает ли система или сломалась.
Многошаговые сценарии: формы, мастеры, анкеты
Если пользователь проходит через несколько шагов, то каждый шаг должен быть описан. Что должно быть заполнено, можно ли вернуться назад, что сохраняется и когда это всё считается завершённым.
Пример:
Given пользователь завершил шаг 1
When он нажимает Далее
Then открывается шаг 2, а данные первого шага сохраняются
Пояснение: многошаговые сценарии сложны тем, что часть логики разбросана по разным экранам. Если ты не опишешь это явно, фронт сделает переход, а бекенд забудет сохранить шаг. Или наоборот всё пересохраняется при каждом клике.
Подводные камни:
Нет проверки обязательных полей перед переходом.
Кнопка Назад очищает данные.
Не описано поведение при закрытии окна. Черновик сохраняется или нет?
Шаблон:
Given [пользователь завершил определённый шаг]
When [он переходит дальше]
Then [данные сохраняются и открывается следующий шаг]
Совет: каждый шаг в многошаговом сценарии - это отдельное состояние системы. Чем чётче описан переход и сохранение, тем стабильнее работает вся логика.
Какой итог
Хорошая документация - это когда ни у одного участника проекта не возникает вопроса «а что должно происходить вот тут». Если ты не зафиксировал поведение, то его придумает кто-то другой. И не факт, что так, как надо.
Пиши так, чтобы не оставалось пространства для домыслов. Это экономит нервы и время (на правках).
Я веду свой ТГ канал #ЯЖАНАЛИТИК, в котором рассказываю о буднях системного аналитика, околоITшной жизни, описываю кейсы, лайфхаки, рабочие неудачи и все то , что тебе потребуется для работы. Простым и доступным языком. Без нудятины и духоты (ну может быть совсем чуть-чуть)