Что такое паттерн Given-When-Then в тестировании?

Ответ

Given-When-Then — это шаблон для структурирования сценариев тестирования и описания поведения в методологиях BDD (Behavior-Driven Development) и ATDD (Acceptance Test-Driven Development). Он делает тесты читаемыми и понятными для всех участников (разработчиков, тестировщиков, аналитиков).

Структура:

  1. Given (Дано): Описывает начальный контекст и предварительные условия теста. Это "подготовка данных".
  2. When (Когда): Описывает ключевое действие или событие, которое тестируется.
  3. Then (Тогда): Описывает ожидаемый результат или постусловия, которые должны быть проверены.

Пример на Java (JUnit):

@Test
public void transferMoney_decreasesSenderBalanceAndIncreasesReceiverBalance() {
    // Given (Дано)
    Account senderAccount = new Account("ACC001", 1000.00);
    Account receiverAccount = new Account("ACC002", 500.00);
    double transferAmount = 300.00;

    // When (Когда)
    senderAccount.transfer(receiverAccount, transferAmount);

    // Then (Тогда)
    assertEquals(700.00, senderAccount.getBalance(), 0.001);
    assertEquals(800.00, receiverAccount.getBalance(), 0.001);
}

Пример на Gherkin (язык для Cucumber, Behat):

Feature: Перевод денег
  Сценарий: Успешный перевод между счетами
    Given на счете "ACC001" есть 1000 рублей
    And на счете "ACC002" есть 500 рублей
    When я перевожу 300 рублей со счета "ACC001" на счет "ACC002"
    Then на счете "ACC001" должно остаться 700 рублей
    And на счете "ACC002" должно стать 800 рублей

Преимущества:

  • Чёткая структура: Делает намерение теста очевидным.
  • Улучшенная читаемость: Тесты становятся документацией к поведению системы.
  • Фокус на поведении: Помогает сконцентрироваться на том, что делает система, а не как.
  • Лёгкая локализация ошибок: Провал на этапе Given, When или Then сразу указывает на природу проблемы.

Ответ 18+ 🔞

А, блядь, Given-When-Then! Ну это ж классика, ёпта, как «Муму» в мире тестов, только без утоплений, слава богу.

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

Вот смотри, как это работает, на пальцах:

  1. Given (Дано) — это, блядь, подготовка. Ты говоришь: «Слушай, вот есть у нас такая хуйня на старте». Допустим, два счёта, на одном тысяча, на другом пятьсот. Всё, стартовые условия задал. Как декорации в театре расставил.
  2. When (Когда) — это само действие, кульминация! Ты нажимаешь на спусковой крючок. «Когда я беру и перевожу триста рублей с первого счёта на второй». Бах! Событие случилось.
  3. Then (Тогда) — а вот тут мы смотрим, что получилось, и сравниваем с ожиданием. «Тогда, сука, на первом должно быть семьсот, а на втором — восемьсот». Если не так — пиши пропало, где-то косяк.

Вот, смотри, как это в коде выглядит, прям как в жизни:

@Test
public void transferMoney_decreasesSenderBalanceAndIncreasesReceiverBalance() {
    // Given (Дано) — готовим сцену
    Account senderAccount = new Account("ACC001", 1000.00);
    Account receiverAccount = new Account("ACC002", 500.00);
    double transferAmount = 300.00;

    // When (Когда) — совершаем действие
    senderAccount.transfer(receiverAccount, transferAmount);

    // Then (Тогда) — проверяем, не обосрались ли мы
    assertEquals(700.00, senderAccount.getBalance(), 0.001);
    assertEquals(800.00, receiverAccount.getBalance(), 0.001);
}

А есть ещё такая штука — Gherkin. Это когда тесты пишутся почти человеческим языком, для всяких менеджеров и аналитиков. Выглядит как сказка на ночь, только про баги:

Feature: Перевод денег
  Сценарий: Успешный перевод между счетами
    Given на счете "ACC001" есть 1000 рублей
    And на счете "ACC002" есть 500 рублей
    When я перевожу 300 рублей со счета "ACC001" на счет "ACC002"
    Then на счете "ACC001" должно остаться 700 рублей
    And на счете "ACC002" должно стать 800 рублей

И в чём, собственно, соль, спросишь ты? А соль в том, что:

  • Всё по полочкам. Глаза не разбегаются. Упал тест на шаге Then? Значит, логика ебёная. Упал на When? Метод-то кривой. Упал на Given? Да ты вообще хуйню какую-то подготовил. Локализация ошибок — просто пиздец!
  • Читается, как роман. Любой новый чел в проекте глянет на такие тесты и сразу въедет, что эта чёрная магия в коде должна делать.
  • Заставляет думать о поведении, а не о том, как там внутри шестерёнки крутятся. Сначала думаешь, что должно происходить, а потом уже лепишь, как это сделать.

Короче, Given-When-Then — это не просто три слова, это, блядь, философия. Подход, который спасает от бардака в тестах и делает их осмысленными. Пользуйся, не ошибёшься.