Что такое BDD?

Behavior-Driven Development (BDD) — практика совместной работы, преодолевающая разрыв между бизнес-стейкхолдерами, разработчиками и тестировщиками. Она использует структурированный естественный язык Gherkin для описания ожидаемого поведения системы.

Центральная идея: определить что должна делать система (поведение) до реализации как она это делает (код).

Синтаксис Gherkin

Gherkin использует три основных ключевых слова:

  • Given — предусловие (начальное состояние)
  • When — действие (что делает пользователь)
  • Then — ожидаемый результат (что должно произойти)

Пример Feature-файла

# features/login.feature
Feature: Авторизация пользователя
  Как зарегистрированный пользователь
  Я хочу войти в свой аккаунт
  Чтобы получить доступ к дашборду

  Scenario: Успешный вход с валидными данными
    Given я на странице логина
    When я ввожу "admin@test.com" как email
    And я ввожу "secret123" как пароль
    And я нажимаю кнопку входа
    Then я должен быть перенаправлен на дашборд
    And я должен видеть "Добро пожаловать, Admin" как приветствие

  Scenario: Неудачный вход с неверным паролем
    Given я на странице логина
    When я ввожу "admin@test.com" как email
    And я ввожу "wrongpassword" как пароль
    And я нажимаю кнопку входа
    Then я должен видеть сообщение об ошибке "Неверные учётные данные"
    And я должен остаться на странице логина

Scenario Outline (Data-Driven BDD)

  Scenario Outline: Вход с различными учётными данными
    Given я на странице логина
    When я ввожу "<email>" как email
    And я ввожу "<password>" как пароль
    And я нажимаю кнопку входа
    Then я должен видеть "<результат>"

    Examples:
      | email           | password  | результат                |
      | admin@test.com  | secret123 | Добро пожаловать, Admin  |
      | editor@test.com | pass456   | Добро пожаловать, Editor |
      | wrong@test.com  | wrong     | Неверные учётные данные  |
      |                 | secret123 | Email обязателен         |

Step Definitions

Step definitions связывают шаги Gherkin с кодом автоматизации:

const { Given, When, Then } = require('@cucumber/cucumber');
const { expect } = require('@playwright/test');

Given('я на странице логина', async function () {
  await this.page.goto('/login');
});

When('я ввожу {string} как email', async function (email) {
  await this.page.fill('[data-testid="email"]', email);
});

When('я ввожу {string} как пароль', async function (password) {
  await this.page.fill('[data-testid="password"]', password);
});

When('я нажимаю кнопку входа', async function () {
  await this.page.click('[data-testid="login-submit"]');
});

Then('я должен быть перенаправлен на дашборд', async function () {
  await expect(this.page).toHaveURL('/dashboard');
});

Then('я должен видеть {string} как приветствие', async function (greeting) {
  await expect(this.page.locator('.welcome-msg')).toHaveText(greeting);
});

Then('я должен видеть сообщение об ошибке {string}', async function (message) {
  await expect(this.page.locator('.error-message')).toHaveText(message);
});

Написание хорошего Gherkin

Бизнес-язык, не технический

# Плохо — слишком технично
Scenario: Тест логина
  Given я перехожу на "https://app.example.com/login"
  When я заполняю "#email" значением "admin@test.com"
  And я кликаю "#login-btn"

# Хорошо — бизнес-поведение
Scenario: Успешный вход
  Given я зарегистрированный пользователь-админ
  When я вхожу с валидными данными
  Then я должен видеть свой дашборд

Декларативный стиль вместо императивного

# Императивный (слишком много шагов)
Scenario: Покупка товара
  Given я открываю браузер
  And я перехожу на главную страницу
  And я кликаю на "Товары"
  And я ищу "Беспроводная мышь"
  And я кликаю на первый результат
  And я кликаю "Добавить в корзину"

# Декларативный (понятное поведение)
Scenario: Покупка товара
  Given я авторизован как покупатель
  When я добавляю "Беспроводная мышь" в корзину
  And я завершаю оформление сохранённым способом оплаты
  Then я должен получить подтверждение заказа

Теги для организации

@smoke @login
Feature: Авторизация пользователя

  @positive @critical
  Scenario: Успешный вход
    Given я на странице логина
    When я вхожу с валидными данными
    Then я должен видеть дашборд

  @negative
  Scenario: Вход с заблокированным аккаунтом
    Given мой аккаунт заблокирован
    When я пытаюсь войти
    Then я должен видеть сообщение о блокировке

Запуск с тегами:

npx cucumber-js --tags "@smoke"
npx cucumber-js --tags "@smoke and not @negative"

BDD с Playwright-BDD

Playwright-BDD интегрирует синтаксис Gherkin напрямую с Playwright:

import { createBdd } from 'playwright-bdd';

const { Given, When, Then } = createBdd();

Given('я на странице логина', async ({ page }) => {
  await page.goto('/login');
});

When('я вхожу с {string} и {string}', async ({ page }, email, password) => {
  await page.fill('#email', email);
  await page.fill('#password', password);
  await page.click('#submit');
});

Then('я должен видеть дашборд', async ({ page }) => {
  await page.waitForURL('/dashboard');
});

Hooks для Setup и Teardown

const { Before, After } = require('@cucumber/cucumber');

Before(async function (scenario) {
  console.log(`Запуск: ${scenario.pickle.name}`);
  this.page = await this.browser.newPage();
});

After(async function (scenario) {
  if (scenario.result.status === 'FAILED') {
    await this.page.screenshot({
      path: `screenshots/${scenario.pickle.name}.png`
    });
  }
  await this.page.close();
});

Анти-паттерны BDD

1. Написание Features после кода

BDD — инструмент совместной работы. Писать features после реализации — значит упускать суть.

2. Слишком много сценариев

Feature с 50 сценариями — знак чрезмерной детализации. Стремитесь к 5-15 сценариям на feature.

3. Cucumber только как инструмент тестирования

BDD — про совместную работу, не только автоматизацию. Если только QA пишет Gherkin, главная польза теряется.

4. Хрупкие Step Definitions

Step definitions, привязанные к конкретным UI-элементам, ломаются при изменении UI. Используйте page objects внутри step definitions.

Встреча «Три Амиго»

Наибольшая ценность BDD — во встрече «Three Amigos», где бизнес, разработка и QA обсуждают функциональность вместе:

  1. Бизнес объясняет желаемое поведение
  2. Разработка спрашивает о граничных случаях и технических ограничениях
  3. QA выявляет сценарии, которые могут быть упущены

Результат: набор Gherkin-сценариев, с которыми все согласны, ещё до написания первой строки кода.

Упражнение: Напишите BDD Feature

Создайте полный feature-файл для корзины покупок e-commerce:

  1. Напишите описание feature (Как… Я хочу… Чтобы…)
  2. Напишите 5 сценариев: добавить товар, удалить, обновить количество, применить промокод, перейти к оформлению
  3. Используйте Scenario Outline с Examples для разных промокодов
  4. Добавьте теги для smoke, regression и позитивной/негативной категоризации
  5. Напишите step definitions для минимум 3 сценариев с page objects

Ключевые выводы

  • BDD использует Gherkin (Given/When/Then) для описания поведения на бизнес-языке
  • Feature-файлы служат живой документацией, понятной всем
  • Step definitions связывают Gherkin с кодом автоматизации
  • Пишите декларативные сценарии о поведении, а не императивные шаги
  • Встреча «Three Amigos» — где реализуется ценность совместной работы BDD
  • Теги для организации и выборочного запуска сценариев