Какие тесты писать первыми, а какие подождут
В молодом продукте тесты нужны там, где ошибка стоит денег, доступа или данных. Остальное может подождать без угрызений совести.
У приложения, собранного с ассистентом, тестов обычно либо нет совсем, либо их много и они проверяют, что кнопка рендерится. Ни то, ни другое не помогает спать спокойно. Тесты — это страховка, а страховать имеет смысл то, что дорого потерять.
Простой фильтр: где ошибка обойдётся тебе дороже всего и где ты узнаешь о ней последним? Туда и идут первые тесты.
Деньги
Всё, что считает, списывает и начисляет. Здесь ошибка не выглядит как ошибка — она выглядит как немного другая сумма, и замечают её через месяц.
Что покрыть:
- расчёт цены: скидки, промокоды, налоги, округление, валюты;
- обработку вебхуков оплаты: повтор события не начисляет дважды, возврат забирает доступ;
- баланс, кредиты, лимиты тарифа: нельзя уйти в минус, нельзя потратить одно и то же дважды при параллельных запросах.
Последний пункт особенно важен: гонку двух одновременных запросов вручную не воспроизвести, а тест с двумя параллельными вызовами — можно.
Доступ
Тесты, которые доказывают, что человек A не видит и не меняет данные человека B. Писать их нужно на уровне API, а не интерфейса: интерфейс эти кнопки и так не показывает.
Минимальный набор на каждый ресурс: чужое не читается, не обновляется, не удаляется; обычный пользователь не может вызвать админский метод; роль из тела запроса игнорируется. Это скучные тесты, их легко написать шаблоном, и они ловят самый дорогой класс ошибок.
Целостность данных
Часть защиты здесь — вообще не тесты, а ограничения в базе: not null, unique, внешние ключи, check. Они срабатывают всегда, а не только когда кто-то запустил тест. Начни с них.
Тесты добавь туда, где ограничений базы не хватает:
- миграции: накатываются на копию реальной схемы и не теряют данные;
- каскадное удаление: удаление аккаунта убирает то, что должно, и не задевает чужое;
- фоновые задачи: повторный запуск не создаёт дубликатов.
Один-два сквозных сценария
Сквозной тест, который проходит регистрацию, ключевое действие и оплату в браузере, медленный и капризный. Но один-два таких теста на главный путь пользователя стоят своих неудобств: они ловят поломки, которые не видны ни одному модулю по отдельности. Больше пока не надо.
Что можно пропустить
- Снимки интерфейса. Снапшот-тесты в молодом продукте, где интерфейс меняется каждую неделю, превращаются в ритуал обновления снимков без чтения.
- Тривиальный код. Геттеры, обёртки, форматирование дат, которое видно глазами.
- Код, который ты собираешься выбросить. Если модуль переписывается в следующем месяце, тесты на его внутренности умрут вместе с ним. Тесты на поведение снаружи — оставь.
- Процент покрытия как цель. Цифра растёт легче всего за счёт кода, который тестировать незачем.
- Тесты, где всё замокано. Если подменена база, платёжка и время, тест проверяет моки. Для денег и доступа лучше настоящая база в контейнере.
Как не дать тестам сгнить
Тесты запускаются в CI на каждый push, и красный тест блокирует выкладку. Иначе через месяц половина из них будет красной, и все к этому привыкнут.
Нестабильный тест либо чинится сразу, либо удаляется. Тест, который падает «иногда», учит команду игнорировать падения — это хуже, чем отсутствие теста.
И одно правило, которое окупается быстрее остальных: каждая найденная ошибка в деньгах, доступе или данных сначала получает тест, который её воспроизводит, и только потом исправление.
Если нужно понять, где в твоём продукте тесты нужны в первую очередь, SUBXCAT может разобрать это и написать первый набор.