Главный эффект TDD лежит в стороне от тестов. Чтобы написать тест первым, приходится заранее решить, как модуль будет вызываться и что вернёт. Проектирование интерфейса случается до реализации, и это меняет форму кода сильнее, чем сами проверки.
Цикл
- Красный: тест написан и падает. Иногда он даже не компилируется, и это нормально.
- Зелёный: код доводят до прохождения теста самым коротким путём, допуская любые упрощения.
- Рефакторинг: убирают дублирование и наводят порядок, тесты при этом остаются зелёными.
Шаги короткие: Бек описывал их длиной в минуты.
Чего TDD не даёт
Покрытие тестами и TDD — разные вещи. Тесты, дописанные после кода, дают ту же цифру покрытия и никак не влияют на устройство модуля. Обратное тоже верно: команда с полным TDD пропустит ошибку, которой нет в тестах, потому что тест проверяет только то, что автор придумал проверить.
Где буксует
Тяжелее всего TDD идёт на коде, плотно сросшемся с внешним миром: интерфейсы, интеграции, унаследованные модули без швов. Обычно там начинают с тестов на уровне поведения, а внутрь спускаются по мере того, как код удаётся разъединить.
- Логика с ветвлениями и расчётами: скидки, тарифы, права доступа
- Код, который будут менять долго и часто
- Исправление ошибки: тест воспроизводит её до правки
- Прототип, который выбросят после проверки гипотезы
- Вёрстка и визуальные детали интерфейса
- Код, целиком состоящий из вызовов внешней системы
В биллинге появляется ошибка: скидка для годовой подписки считается от суммы, к которой уже применили скидку за объём. Разработчик начинает с теста, который повторяет случай клиента и падает. Затем правит расчёт до зелёного. Затем разносит два вида скидок по отдельным функциям, потому что тест уже страхует поведение. Тест остаётся в наборе и ловит ту же ошибку через полгода при переписывании тарифов.
Начинайте с ошибок. Правило «на каждый баг сначала тест» приживается легче, чем полный переход на цикл, и сразу даёт видимую пользу: одна и та же ошибка перестаёт возвращаться. В карточке задачи на исправление удобно держать ссылку на тест — при разборе повторного обращения сразу видно, что именно проверяется.