TDD: разработка через тесты
TDD — цикл Red-Green-Refactor: сначала пишем падающий тест, потом минимальный код для прохождения, потом улучшаем
Почему это важно: TDD заставляет думать о дизайне API до написания реализации; результат — более тестируемый, модульный и понятный код
Главная идея
тест — это первый клиент кода. Если тест сложно написать — значит дизайн кода сложен. TDD улучшает дизайн через обратную связь
Как это выглядит на практике
- Red: пишем тест для несуществующей функции calculate_discount(order). Тест падает: NoMethodError.
- Green: пишем минимальный код: def calculate_discount(order); 0; end. Тест проходит.
- Refactor: дорабатываем реализацию с правильной логикой, сохраняя зелёный тест.
- Следующий тест: calculate_discount для order > 1000 возвращает 10%. Red → Green → Refactor.
- Итог: покрытие по умолчанию, API продуман до реализации.
Что происходит под капотом
- Emergent design: архитектура возникает из требований тестов, не из upfront-планирования.
- Test-first заставляет писать модульный код: нельзя написать тест для класса с 10 зависимостями без их инъекции.
- 'Fake it till you make it': начинаем с хардкода, затем обобщаем. Тесты направляют обобщение.
- London school (mockist) vs Detroit school (classicist): разные подходы к тому, что мокировать в TDD.
Типичные ошибки и заблуждения
- Ошибка: TDD замедляет разработку. В краткосрочной перспективе — немного; долгосрочно — ускоряет за счёт меньшего дебаггинга и безопасного рефакторинга.
- Ошибка: TDD требует 100% coverage. TDD — инструмент дизайна; coverage — побочный эффект, а не цель.
- Ошибка: нельзя применять TDD к существующему коду. Legacy code можно покрывать тестами итеративно, начиная с новых фич.
- Ошибка: TDD означает тестировать каждый метод. Тестируй поведение, а не каждую строку.
Ключевые выводы
- Red → Green → Refactor — три фазы TDD.
- Тест пишется до кода — это меняет мышление о дизайне.
- Рефакторинг безопасен только при зелёных тестах.
- TDD = дизайн-инструмент + тестовое покрытие в одном.
Термины урока
Связь с работой backend-разработчика
TDD работает лучше всего для бизнес-логики (сервисы, вычисления, трансформации). Для CRUD-эндпоинтов достаточно интеграционных тестов после. Выбирай инструмент под задачу.
Мини-разбор реальной ситуации
Разработчик пишет сложную функцию расчёта стоимости доставки (зоны, вес, скидки). Без TDD: 2 часа кода, 1 час дебаггинга, несколько пропущенных edge cases. С TDD: каждый edge case — сначала тест, потом код. Результат за то же время: полное покрытие, ни одного бага в продакшене.
Что запомнить
- Red → Green → Refactor: строго по порядку.
- Тест — первый клиент кода: если писать тест сложно, дизайн кода плохой.
- Рефакторинг только при зелёных тестах.
Итог
TDD — это не про тесты, а про дизайн. Тесты — артефакт процесса. Главная ценность — более продуманный, модульный и понятный код.