Просить нейросеть «написать тесты» — почти бесполезно: получите десяток проверок, которые повторяют реализацию и проходят всегда. Польза появляется, когда AI используют для генерации гипотез о поведении, а проверку оставляют человеку и инструментам.
Где AI действительно экономит время
Три задачи, где модель сильна:
- придумать граничные случаи, которые вы не заметили;
- превратить список правил в набор тестовых методов;
- объяснить упавший тест и предложить, что именно он проверяет.
Плохо она справляется с неявным контекстом: бизнес-правилами, которые нигде не записаны, и деталями фреймворка вашей версии. Если дать только имя класса, модель начнёт выдумывать методы, которых нет.
Что дать модели
Минимальный контекст, без которого результат бесполезен:
- версия PHP и фреймворка, тестовый раннер (PHPUnit или Pest);
- полный текст класса или метода, а не только название;
- правила предметной области списком;
- пример существующего теста из проекта — стиль важнее теории;
- ограничения: без обращения к сети, без реальной БД, без
sleep().
Если класс большой, передавайте его частями. Модель с длинным контекстом хуже удерживает детали, чем модель с коротким и точным.
Промпт, который даёт результат
Рабочая структура — не «напиши тесты», а «составь таблицу случаев, потом код».
Ты помогаешь писать тесты для PHP 8.3 + PHPUnit 11.
Вот класс Cart с методами add(), remove(), total().
Правила: скидка 10% от 5000 ₽, доставка бесплатна от 3000 ₽,
количество не может быть отрицательным.
Шаг 1. Составь таблицу: входные данные, ожидаемый результат,
тип случая (норма / граница / ошибка).
Шаг 2. Для каждой строки напиши отдельный тест.
Не используй методы, которых нет в классе.
Не подключай внешние библиотеки.
Разделение на два шага важно: сначала вы проверяете список случаев и правите его, потом модель пишет код. Если сразу просить тесты, ошибки в понимании задачи замаскируются синтаксически правильным кодом.
Что проверять в сгенерированных тестах
Тест отличается от рабочего кода тем, что его ошибка опаснее: зелёный, но бесполезный тест создаёт ложную уверенность. Проверяйте:
- утверждение действительно проверяет результат, а не факт вызова метода;
- нет проверки реализации. Тест не должен ломаться от рефакторинга, если поведение сохранилось;
- ожидаемые значения посчитаны вручную, а не получены вызовом тестируемого кода;
- границы включены: ноль, минус, пустая строка,
null, максимальное значение; - моки не скрывают логику. Если замокан сам объект проверки, тест проходит всегда;
- нет зависимости от времени и порядка.
now(), случайные числа и файловая система делают тест нестабильным.
Отдельно проверьте, что тест падает, если сломать код. Это простейший тест на осмысленность: закомментируйте строку в методе и запустите набор.
public function test_total_is_zero_for_empty_cart(): void
{
$cart = new Cart();
$this->assertSame(0, $cart->total());
}
Если такой тест проходит и после удаления всей логики метода, он ничего не проверяет.
Мутационное тестирование как объективная проверка
Инструмент вроде Infection вносит мелкие изменения в код — меняет + на -, убирает условие — и смотрит, падает ли тест. Если мутация выжила, значит, поведение не покрыто.
Запускать мутационное тестирование на всём проекте долго, начните с одного модуля. Даже 60–70% убитых мутантов в критичном классе говорят больше, чем 100% строкового покрытия.
Границы применимости
AI не знает, что считается правильным поведением. Он оптимизирует правдоподобие, а не истину. Поэтому бизнес-правила должны приходить от вас, а не выводиться моделью из кода.
Не стоит доверять генерацию тестов для безопасности: проверки авторизации, подписи, ограничения доступа лучше писать вручную и дополнять имитационными атаками. И не вставляйте в промпт реальные персональные данные или секреты.
Полезные смежные материалы: промпты для генерации кода и RAG: поиск по документам. Если тесты падают из-за лишних запросов к базе, пригодится статья про N+1 в Eloquent.
Рабочий процесс
- Сформулируйте правила и границы вручную.
- Попросите таблицу случаев, отредактируйте её.
- Сгенерируйте тесты по одной группе за раз.
- Запустите, убедитесь, что они падают на старом коде, если проверяют новый баг.
- Проверьте мутациями и code review.
- Оставьте только тесты, которые ловят реальные ошибки.
Коротко
- AI силён в генерации случаев, а не в знании вашего кода;
- давайте класс, версии, правила и пример стиля;
- сначала таблица случаев, потом код;
- проверяйте, падает ли тест при поломке логики;
- мутационное тестирование показывает реальное покрытие.