Что такое тесты и TDD простыми словами
Чтобы новая фича не сломала три старых втихую
Тесты и TDD простыми словами: зачем писать проверку до кода, как работает цикл красный-зелёный и почему тесты ловят баги раньше, чем их увидит пользователь.
Что такое тест простыми словами
Собрал шкаф из IKEA. Дверца открывается, полки стоят - красота, хоть в сторис выкладывай. Через неделю прикручиваешь новую полку и нечаянно перекашиваешь дверцу. А ты этого не видишь. Увидишь через месяц - когда дверца торжественно отвалится тебе на ногу.
Чтобы такого не было, придумали тесты. Тест Тест - маленькая программа-проверяльщик. Она сама запускает твой код, подаёт ему данные и проверяет, что результат правильный. Если что-то не так - громко кричит «сломалось». - это робот, который после каждой твоей правки обходит весь шкаф и дёргает каждую дверцу: открывается? закрывается? не перекошена? Дёрнул - и сразу доложил. «Всё ок» или «вот тут отвалилось, чини».
А TDD - это просто привычка. Сначала позвать робота-проверяльщика, и только потом строить.
Зачем тесты нужны вайбкодеру
Ты вайбкодер. Тесты руками ты не пишешь - их напишет агент. Но если понимаешь, зачем они вообще, то получаешь сразу четыре приятных бонуса:
- перестаёшь бояться трогать код - робот сам скажет, если что-то поехало;
- ловишь баги до того, как их заметит пользователь (а тем более заказчик);
- спокойно просишь агента «перепиши покрасивее» - тесты подстрахуют;
- и наконец понимаешь, зачем агент «сначала пишет проверку, которая падает». Это не глюк. Это метод.
Разница между «мой сайт постоянно где-то ломается, и я не понимаю где» и «меняю что хочу и сплю спокойно» обычно сводится к одному слову: тесты.
Цикл TDD: красный, зелёный, причесать
Просишь агента работать по TDD - и он не кидается писать код наобум. Он идёт по чёткому циклу. Вот он, без заумных слов.
Шаг 1. Описываем, чего хотим
Сначала агент формулирует задачу глазами пользователя: «Я как покупатель хочу искать товары по смыслу, чтобы находить нужное даже без точных слов». Это называется user journey User journey - короткая история «кто хочет что и зачем». Помогает понять, что вообще надо проверять, ещё до написания кода. . Из неё сразу ясно, что проверять.
Шаг 2. Пишем тест - и он СПЕЦИАЛЬНО падает
Дальше начинается странное. Агент пишет проверку до кода. Понятно, что она тут же падает - кода-то ещё нет! Это и есть красный RED (красный) - состояние, когда тест написан, запущен и упал. Это нормально и обязательно: так мы убеждаемся, что тест вообще работает и реально проверяет нужное. этап.
Шаг 3. Пишем минимум кода, чтобы тест позеленел
Теперь агент пишет ровно столько кода, чтобы тест прошёл. Ни строчкой больше. Тест из красного становится зелёным GREEN (зелёный) - тест запущен после написания кода и прошёл. Значит, нужное поведение действительно работает. . Робот доволен. Ты тоже.
Шаг 4. Наводим красоту (рефакторинг)
Код работает, но выглядит, мягко говоря, как попало. Вот теперь его можно причёсывать - убрать дубли, переименовать понятнее. И после каждого шага гонять тесты: пока они зелёные - ты ничего не сломал.
Виды тестов: юнит, интеграция, E2E
Тесты бывают трёх «размеров» - от мелкого к крупному. Хороший агент покрывает все три, а не один любимый.
- Юнит - проверяет одну маленькую деталь: «функция складывает 2 и 2 и выдаёт 4?». Быстро и точечно.
- Интеграция - проверяет, что детали дружат: «кнопка реально достаёт данные с сервера?».
- E2E (от начала до конца) - робот открывает сайт как живой человек: кликает, печатает, проверяет результат.
- «Красиво ли» - дизайн тест не оценит, это решаешь ты глазами.
- То, что не описал - робот проверяет ровно то, о чём его попросили, и ни байтом больше.
- «Удобно ли людям» - UX чувствуешь ты, а не машина.
Хороший тест против плохого: как отличить
Самая частая засада: тест вроде есть, а проверяет не то. Вот как отличить надёжного робота от декоративного. Это прямо из правил скилла tdd-workflow.
- Проверяет то, что видит пользователь: «на экране написано Корзина: 3».
- Цепляется за смысл: «кнопка с текстом Купить», а не за случайный класс.
- Независимый: сам готовит свои данные и ни от кого не зависит.
- Проверяет и плохие сценарии: пустой ввод, ошибка сервера, странные числа.
- Лезет в кишки: «а переменная count точно равна 5?» - пользователю на это плевать.
- Цепляется за хрупкое: «кликни по css-class-xyz» - поменяли стиль, тест упал.
- Зависит от соседа: один тест создал юзера, другой надеется, что тот ещё жив.
- Проверяет только когда всё хорошо - а в реальности данные кривые сплошь и рядом.
Пример из жизни: как промокод ломает корзину
Сделал интернет-магазин. Корзина считает сумму - работает. Через неделю просишь агента: «добавь скидочный промокод». Он добавляет. Промокод работает! Ты радуешься и со спокойной душой идёшь спать.
А наутро сюрприз: после добавления промокода обычная сумма без скидки начала считаться с копеечной ошибкой. Ты этого не заметил, потому что проверял только промокод. Зато заметил клиент - и оставил тёплый отзыв на одну звезду.
С тестами этого бы не было. Робот-проверяльщик после правки промокода сам пересчитал бы и обычную корзину, и заорал бы: «эй, тут теперь 99 рублей вместо 100, чини». За три секунды - до сна, а не после.
Вот как попросить агента работать так, чтобы он тебя страховал:
Добавь в корзину поддержку скидочных промокодов. Работай строго по TDD:
- Сначала опиши простыми словами, что должно происходить: что вводит пользователь и что он должен увидеть.
- Напиши тесты ДО кода. Обязательно проверь и обычную корзину без промокода - я хочу быть уверен, что её не сломали.
- Запусти тесты и покажи мне, что новый тест падает. Это нормально, так и должно быть.
- Теперь напиши минимум кода, чтобы все тесты стали зелёными.
- Запусти тесты снова и покажи, что всё зелёное.
- Проверь крайние случаи: пустой промокод, несуществующий промокод, скидка больше суммы.
Как поймать тесты, написанные «для галочки»
Бывает, агент торопится и делает вид, что протестировал. Пробеги по чек-листу - это прямо суть скилла tdd-workflow.
- Тест реально падал? Агент сразу показал зелёное, не показав красное? Возможно, тест не проверяет ровным счётом ничего.
- Старое прогнали? Новая фича не должна ломать то, что работало. Спроси в лоб: «а старое ты проверял?».
- Есть плохие сценарии? Пустой ввод, ошибка, странные числа - не только «когда всё хорошо».
- Тест цепляется за смысл, а не за стиль? «Кнопка Купить», а не безымянный css-класс.
- Тесты независимы? Каждый сам готовит данные и не надеется на соседа.
Частые ошибки новичков в TDD
- Просить код без тестов. «Просто сделай» - а потом удивляться поломкам. Добавляй «работай по TDD».
- Верить зелёному, не видев красного. Тест ни разу не падал? Значит, может, и не проверяет ничего.
- Тестировать только новую фичу. Главная польза тестов - поймать, что новое сломало старое.
- Проверять только «когда всё хорошо». Реальные данные бывают пустые, кривые и злые.
- Цепляться за хрупкое. Тест по css-классу падает от любой смены дизайна. Цепляйся за смысл.
- Сносить тесты, когда они мешают. Падающий тест - не враг. Это робот, который только что спас тебе ногу.
TL;DR - если коротко
- Тест - робот-проверяльщик: сам жмёт кнопку и докладывает «работает» или «всё, сломалось».
- TDD - привычка писать проверку до кода. Сперва красный - тест падает. Потом зелёный - код его чинит.
- Тесты ловят не первый баг, а возвращающиеся - когда свежая фича тихо ломает старую.
- Хороший тест смотрит на то, что видит пользователь, а не как оно устроено внутри.
- Скажи агенту «работай по TDD» - он сам напишет тесты, увидит провал, починит и перепроверит.
- Зелёный тест, который ты ни разу не видел красным, - не страховка. Это самообман.