BDD на JavaScript: пишем тесты, которые понимает бизнес

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как объяснить программисту, что баг — это не «оно не работает»?

Вы когда-нибудь получали задачу в стиле: «Сделай, чтобы кнопка работала правильно»? Или, что ещё хуже, писали код, тесты зелёные, а заказчик говорит: «Ну, это не то, что я просил». Знакомая боль? Добро пожаловать в мир, где BDD (Behaviour-Driven Development) на JavaScript становится спасательным кругом.

BDD — это не просто очередная модная аббревиатура. Это подход, который заставляет разработчиков, тестировщиков и бизнес-аналитиков говорить на одном языке. На русском, живом, без «методологий» и «архитектурных парадигм». Сегодня мы разберём, как внедрить BDD в JavaScript-проект, напишем реальные тесты и поймём, почему это делает код чище, а жизнь — проще.


Что такое BDD и чем он отличается от TDD?

Давайте сразу расставим точки над «ё». BDD (Behaviour-Driven Development) — это эволюция TDD (Test-Driven Development). Если TDD говорит: «Сначала напиши тест, потом код», то BDD добавляет: «Но тест должен быть понятен бабушке-инвестору».

Ключевая идея BDD: мы тестируем поведение системы, а не её внутреннее устройство. Мы не спрашиваем: «Возвращает ли функция true?». Мы спрашиваем: «Может ли пользователь добавить товар в корзину и увидеть сумму заказа?». Разница колоссальная.

Для BDD на JavaScript существует специальный язык — Gherkin. Это такой псевдо-английский (или псевдо-русский), который выглядит как инструкция к конструктору Lego:

Функционал: Корзина покупок
  Как зарегистрированный пользователь
  Я хочу добавлять товары в корзину
  Чтобы видеть итоговую стоимость

  Сценарий: Добавление одного товара
    Допустим пользователь авторизован
    Когда он добавляет товар "Ноутбук" в корзину
    Тогда в корзине отображается 1 товар
    И общая стоимость равна 99900 рублей

Согласитесь, это читается как бизнес-требование, а не как код. И это главная фишка BDD.


Инструменты для BDD на JavaScript

Чтобы заниматься behaviour-driven development на JavaScript, нужны правильные инструменты. Вот три кита, на которых всё держится:

  • Cucumber.js — самый популярный фреймворк для BDD. Он парсит Gherkin-сценарии и связывает их с кодом.
  • Jest + Jest-Cucumber — если вы уже используете Jest, это идеальный вариант. Никакой магии, только чистая интеграция.
  • Mocha + Chai + Gherkin — для тех, кто любит собирать конструктор вручную. Гибко, но больше кода.

Мы будем использовать Cucumber.js, потому что это стандарт индустрии. Установка простая:

npm install @cucumber/cucumber --save-dev

После этого создаём папку features/ — там будут жить наши .feature файлы. А в папке step_definitions/ — код, который оживляет сценарии.


Пишем первый BDD-тест: авторизация пользователя

Давайте представим, что мы делаем интернет-магазин. Первое, что нужно протестировать — вход в систему. Создаём файл features/login.feature:

# language: ru
Функционал: Авторизация пользователя
  Как посетитель сайта
  Я хочу войти в личный кабинет
  Чтобы управлять своими заказами

  Сценарий: Успешный вход с правильными данными
    Допустим я нахожусь на странице входа
    Когда я ввожу email "user@example.com" и пароль "123456"
    И нажимаю кнопку "Войти"
    Тогда я вижу приветствие "Добро пожаловать, Иван!"

Теперь нужно написать шаги (steps) — код на JavaScript, который выполнит эти действия. Создаём step_definitions/login.steps.js:

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

// Состояние приложения (имитация)
let currentPage = '';
let userEmail = '';
let userPassword = '';
let isLoggedIn = false;
let greetingMessage = '';

Given('я нахожусь на странице входа', function () {
  currentPage = 'login';
  isLoggedIn = false;
});

When('я ввожу email {string} и пароль {string}', function (email, password) {
  userEmail = email;
  userPassword = password;
  // Тут мог бы быть вызов реального API
  if (email === 'user@example.com' && password === '123456') {
    isLoggedIn = true;
    greetingMessage = 'Добро пожаловать, Иван!';
  }
});

When('нажимаю кнопку "Войти"', function () {
  // Действие уже выполнено в предыдущем шаге
});

Then('я вижу приветствие {string}', function (expectedMessage) {
  expect(greetingMessage).to.equal(expectedMessage);
});

Запускаем тесты командой npx cucumber-js. Если всё зелёное — вы только что написали первый BDD-тест. Поздравляю!


Продвинутый сценарий: проверка негативных кейсов

BDD особенно силён в описании граничных случаев. Добавим ещё один сценарий в наш файл login.feature:

  Сценарий: Ошибка при неверном пароле
    Допустим я нахожусь на странице входа
    Когда я ввожу email "user@example.com" и пароль "wrongpass"
    И нажимаю кнопку "Войти"
    Тогда я вижу сообщение об ошибке "Неверный email или пароль"

Дописываем шаги в login.steps.js:

let errorMessage = '';

When('я ввожу email {string} и пароль {string}', function (email, password) {
  userEmail = email;
  userPassword = password;
  // Негативный сценарий
  if (email === 'user@example.com' && password !== '123456') {
    isLoggedIn = false;
    errorMessage = 'Неверный email или пароль';
  }
});

Then('я вижу сообщение об ошибке {string}', function (expectedError) {
  expect(errorMessage).to.equal(expectedError);
});

Обратите внимание: мы не трогаем код приложения. Мы просто описываем поведение. Если тест падает — значит, либо логика в шагах неверна, либо сама бизнес-логика не соответствует ожиданиям.


BDD в реальном проекте: как не выстрелить себе в ногу

Теперь, когда вы знаете теорию, давайте поговорим о практике. Behaviour-driven development — это не панацея. Вот несколько граблей, на которые наступают новички:

  • Не пишите сценарии на каждый чих. BDD для критически важного поведения, а не для проверки геттеров и сеттеров.
  • Исп

Блоги

Рекомендаций по книгам