TDD и BDD: подходы к написанию тестов до кода
Введение: Почему тесты до кода — это круто? 🎯
Знакомо ли тебе чувство, когда после недели кодинга внезапно обнаруживаешь, что баги множатся как кролики? 🔍 TDD и BDD — два подхода, которые переворачивают разработку с ног на голову: сначала тесты, потом код. Это как строить дом с чертежом, а не надеяться, что стены сами сложатся в замок.
TDD (Test-Driven Development) 🛠️
Суть подхода
- Красный тест → Зеленый тест → Рефакторинг. Это цикл TDD:
- Пишешь тест для несуществующей функциональности (он падает).
- Пишешь минимальный код, чтобы тест прошел.
- Улучшаешь код, сохраняя "зеленый" статус.
🔥 Совет: TDD — это не про тестирование, а про дизайн кода. Он заставляет думать о требованиях до реализации.
Пример: Калькулятор на JavaScript
// 1. Красный тест (ожидаем функцию `sum`)
describe('Calculator', () => {
it('should return 4 when adding 2 and 2', () => {
assert.equal(sum(2, 2), 4); // Упс, функция `sum` не существует!
});
});
// 2. Пишем минимальную реализацию
function sum(a, b) {
return 4; // "Чит" для прохождения теста
}
// 3. Рефакторинг (теперь код универсален)
function sum(a, b) {
return a + b;
}
BDD (Behavior-Driven Development) 🌿
Чем отличается от TDD?
BDD фокусируется на поведении системы и читаемости тестов для не-технических специалистов. Здесь тесты пишутся на языке, похожем на естественный:
- Given (Дано) → When (Когда) → Then (Тогда).
Пример: Авторизация пользователя
describe('User Login', () => {
it('should block after 3 failed attempts', () => {
// Given
const user = new User('admin');
// When
user.login('wrong');
user.login('wrong');
user.login('wrong');
// Then
expect(user.isBlocked).toBe(true);
});
});
💡 Фишка: BDD-тесты часто пишутся в связке с Cucumber или Jest, а их тексты могут понимать даже менеджеры!
TDD vs BDD: Что выбрать? ⚖️
| Критерий | TDD | BDD |
|---|---|---|
| Фокус | Техническая реализация | Поведение системы |
| Язык | Код (assert, expect) | Естественный (Given-When-Then) |
| Для кого | Разработчики | Команда (включая QA, PM) |
| Инструменты | Jest, Mocha | Cucumber, Jasmine |
Типичные ошибки новичков 🚨
- Тесты как документация. Если тест не падает при удалении кода — он бесполезен.
- Избыточные проверки. Тестируй только публичное поведение, а не каждый if-else.
- Игнорирование рефакторинга. Зеленый тест — не повод остановиться.
// Плохо: тест не ломается при изменении логики
function isEven(num) {
return num % 2 === 0;
}
it('should return true for 2', () => {
expect(isEven(2)).toBe(true); // Что, если заменить на `return true`?
});
// Лучше: несколько кейсов
it('should detect even numbers', () => {
expect(isEven(2)).toBe(true);
expect(isEven(3)).toBe(false);
});
Как внедрить это в реальные проекты? 🏗️
- Начни с малого. Протестируй одну функцию в стиле TDD.
- BDD для сложных сценариев. Например, платежи или onboarding.
- Интеграция в CI/CD. Тесты должны запускаться автоматически.
Итог: Ты — архитектор, а не пожарный 🧙♂️
С TDD/BDD ты предотвращаешь баги, а не героически чинишь их ночью. Пиши тесты, будто от них зависит твоя репутация — потому что так оно и есть!