
Самая распространённая фраза, которую я слышу про тесты, — «некогда».
Не «не вижу пользы». Не «дорого». Не «у меня архитектура плохая, нечего тестировать». Именно — «некогда». Времени нет.
Я в это уже не верю. Потому что почти каждый, кто это говорит, в этот же момент уже делает работу теста. Просто руками. Без записи. Без повторного запуска. Без CI. Один раз и забыл.
Давайте по пунктам.
«Я настраиваю Postman»
Любимое. Открыт Postman, в нём пять вкладок, в каждой собирается тело запроса, подбираются хедеры, потом «send», смотришь ответ, что-то меняешь, опять «send».
Это API-тест. Только без файла.
Ты только что описал ожидаемый запрос и ожидаемый ответ — это и есть содержание теста. Сохрани коллекцию, нажми «export», переведи в pytest / Pest / PHPUnit / что у тебя там. В следующий раз нажмёшь одну кнопку вместо часа кликов в Postman.
И ещё ловушка: твой Postman знает только то, что ты сегодня туда вбил. Через две недели ты половину забудешь и будешь собирать заново.
«Я проверяю скидки через интерфейс»
Это вообще классика. Логика сложная: правила, корзина, накопительные скидки, периодические акции, исключения для категорий. Ты создаёшь правило, добавляешь в корзину товар, открываешь калькулятор, считаешь сам, сверяешь.
Это юнит-тест на калькулятор скидок. Где-то у тебя в коде есть метод calculateDiscount. Засунь его на стенд, прогони на нём ту же таблицу, что у тебя сейчас в голове. Десять строк теста — и калькулятор перепроверится сам.
Если метод нельзя «засунуть на стенд» отдельно — это уже не «некогда писать тесты», это «у меня архитектура такая, что тестировать нечем». Другая проблема, другой разговор.
«Я после фикса гоняю позитивные сценарии руками»
Ты пишешь happy path. Просто кожаными руками. Раз за разом, каждый коммит, по одному и тому же чек-листу.
Через пять итераций этот чек-лист — и есть твой тестовый набор. Перепиши его в код. Один раз потратишь полтора часа. Дальше — make test за десять секунд.
Аргумент «но мой happy path меняется» — не аргумент. У тебя сейчас он тоже меняется. Только ты его держишь в голове и иногда забываешь шаг.
«Тестеры вернули таску — я сломал второй сценарий»
Самая болезненная категория, потому что это уже не «некогда». Это уже стоило тебе времени.
Ты сделал сценарий А. Ты не проверил, что не сломался сценарий Б — потому что про Б ты не помнил. Тестеры вернули. Ты чинишь Б. Заодно ломаешь В, потому что про В ты тоже не помнил.
Это e2e-тесты. Их единственная задача — помнить за тебя то, что в голове не удерживается.
Тебе не «некогда» их писать. Тебе их больно, потому что ты не написал их в прошлый раз и расплачиваешься сейчас.
«Я чиню баг, который сам чинил месяц назад»
Открываешь блейм — там твой коммит, месячной давности, с твоим же именем. Тот самый баг. Ты его уже чинил. Но кто-то за это время поправил твой фикс — посчитал странным, упростил, отрефакторил «по-человечески» — и баг вернулся.
Теперь ты сидишь и третий раз руками воспроизводишь сценарий, который уже два раза разбирал.
Без теста этот баг будет возвращаться вечно. Не потому что коллеги злые, а потому что твой фикс выглядит как «странная строчка без объяснений». Любой нормальный человек захочет её «причесать».
Тест в этой ситуации — не «дополнительная работа», а страховочная сетка:
- Воспроизводишь баг в тесте — он красный.
- Делаешь фикс — он зелёный.
- Коммитишь оба.
Дальше любой, кто захочет «улучшить» твою странную строчку, увидит красный билд. И не «улучшит». А если очень хочет — пусть сначала объяснит, что не так с тестом.
Без этой сетки твой фикс — приговорённый. Через полгода ты будешь чинить его в четвёртый раз.
«Я пишу test.php для коллеги, чтобы показать как вызывается»
Жанр «test.php в корне репозитория, не закоммичен, иногда лежит в /tmp/». Коллега не понимает, как вызвать твой класс. Ты ему показываешь — три строчки кода с примером, кидаешь в слак.
Это хуже документации.
Документация хотя бы лежит в одном месте, у неё есть автор, её читают новые сотрудники. А твой test.php:
- никем не проверяется,
- никем не обновляется,
- через неделю никто не помнит, что он есть,
- через две недели сигнатура поменялась и
test.phpлежит мёртвый, - через месяц коллега опять подходит с тем же вопросом.
Ты выполнил работу теста — описал, как вызывается код, какие у него зависимости, какой ожидаемый результат. И выкинул.
Оформи как обычный тест в проекте. Коллега не «получит письмо со скриптом», а склонирует репозиторий и сразу запустит. CI заодно следит, что пример не протух. Один раз потратишь, всю жизнь работает.
«Я в документации пишу примеры использования»
Хорошее дело, не спорю. Только примеры в документации имеют одну неприятную особенность: они молча устаревают.
Поменялся API — пример в README.md остался. Никто не упадёт. Все думают, что работает. До первого нового пользователя, который скопипастит и удивится.
Тесты — это документация, которая орёт, когда она устарела. Поломал поведение — упали. Не поломал — зелёные.
Самое простое решение: пиши примеры внутри тестов. В документации давай ссылку на тест-файл. Всё, документация теперь самопроверяющаяся. Можно идти отдыхать.
«Я борюсь со связанным кодом, рефакторю»
Любимый сюжет: «не могу переиспользовать функцию, она привязана к контексту, рефакторю всю неделю».
Сюрприз. Тесты — это и есть переиспользование.
Если ты можешь дёрнуть свой код из теста — значит, у него есть нормальный вход и нормальный выход. Значит, его можно дёрнуть из любого другого места. Значит, твой следующий рефакторинг не превратится в недельный квест.
Если не можешь — у тебя не код, а монолит на спичках. И ты не «рефакторишь». Ты страдаешь.
«Для маленького рефакторинга я читаю сто классов»
Тебе надо переименовать одно поле. Или поменять сигнатуру одного метода. Или вынести логику из одного места в другое.
Ты лезешь в IDE, смотришь «find usages», получаешь список из ста файлов. Дальше — день чтения. Что-то ты пропустишь, что-то поймёшь неправильно, что-то «должно работать так же, но я не уверен». В итоге делаешь, мерджишь, через неделю прилетает баг из места, до которого ты не доглядел.
Ты не «осторожный». Ты испуганный.
И тебе страшно — потому что система ничего не гарантирует. Никто не сказал «вот этот метод обязан вернуть строку из латиницы, не пустую, не длиннее 64 символов». Поэтому когда ты собираешься его поменять, ты не знаешь, что зависит от этих свойств.
С тестами ты бы менял строчку и смотрел на цвет. Зелёные — значит, ничего важного не отвалилось. Красные — вот тебе ровно тот список мест, на которые повлияло. Без вычитывания ста файлов руками.
Жаль, что ты был занят и не писал тесты. Это твоё «занят» из прошлого квартала вернулось к тебе сегодня в виде «дня чтения чужого кода».
«Я попросил агента протестировать API. Он написал скрипты, я их выкинул»
А вот тут я в ярости.
Раньше у меня было какое-то оправдание для людей — мол, ну ладно, писать тесты руками лень, понимаю. Теперь оправдания нет.
Агент уже написал тесты. Бесплатно. За тридцать секунд. Идеальный исполнитель тупой работы.
А ты их выкинул. Просто потому что попросил его «протестировать API», а не «написать тесты на API». Одно слово — и ты потерял весь результат.
Скажи правильно: «оформи как нормальный тест в проекте, добавь в нужную папку, прогони, чтобы был зелёный». Всё. У тебя уже есть тест-кейс. Бесплатно.
Это, кстати, я ещё рассказывал в «Промпт не поможет» — формулировка решает почти всё.
А вы не пробовали детский сортер?
Когда я смотрю на программиста, который три часа кликает в Postman и говорит «некогда тест», у меня в голове картинка: взрослый мужчина сидит на полу перед детским сортером — кубик в кубик, треугольник в треугольник — и пытается засунуть звезду в круглое отверстие. Часами. С серьёзным лицом.
Все вокруг шепчут: «возьми треугольную дырку». А он: «некогда, я звезду пристраиваю».
Все эти отмазки — про то же самое. Ты уже взял в руки фигуру. Дырка совсем рядом. Просто тебе кажется, что вставить её туда — отдельная работа, на которую нет времени.
Это не отдельная работа. Это часть той же работы, которую ты и так делаешь.
Вывод
«Некогда писать тесты» — это почти всегда «я уже это делаю, просто руками и без записи».
Тесты не отнимают время. Они фиксируют ту работу, которую ты и так выполняешь. Postman, ручной чек-лист, сверка с калькулятором, регресс после фикса, починка возвращающегося бага, test.php для коллеги, примеры в доке, рефакторинг с вычитыванием ста файлов — это всё уже тесты. Без файла, без CI, без памяти.
С агентами это правило стало злее. Раньше можно было сказать «держу в голове, я опытный». Теперь у тебя в голове агент, и он держать ничего не умеет. Если тестов нет — у него нет никакого способа знать, что он что-то сломал. А он сломает, не сомневайся.
Перестаньте говорить «некогда». Скажите честно: «не умею» или «не хочу». С этим хотя бы можно работать. С «некогда» — нельзя, потому что это неправда.
Найдите тот ручной шаг, который вы повторяете третий раз — и зафиксируйте. Один.
Это уже больше, чем у 80% команд.