Просить нейросеть «написать тесты» — почти бесполезно: получите десяток проверок, которые повторяют реализацию и проходят всегда. Польза появляется, когда 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.

Рабочий процесс

  1. Сформулируйте правила и границы вручную.
  2. Попросите таблицу случаев, отредактируйте её.
  3. Сгенерируйте тесты по одной группе за раз.
  4. Запустите, убедитесь, что они падают на старом коде, если проверяют новый баг.
  5. Проверьте мутациями и code review.
  6. Оставьте только тесты, которые ловят реальные ошибки.

Коротко

  • AI силён в генерации случаев, а не в знании вашего кода;
  • давайте класс, версии, правила и пример стиля;
  • сначала таблица случаев, потом код;
  • проверяйте, падает ли тест при поломке логики;
  • мутационное тестирование показывает реальное покрытие.