Генерация тестов с ИИ: как получить тесты, которые ловят ошибки

Агент пишет тесты быстро, и покрытие растёт за день. Проблема в том, что сгенерированный тест часто проверяет текущее поведение кода, включая его ошибки. Полезные тесты получаются, когда агент пишет их от требований, а результат проходит фильтр: тест собирается, стабильно проходит, ловит изменения в коде и проверяет то, что записано в спеке.

Обновлено 12 ноября 2026, 9 мин чтения

Тесты, которые подтверждают ошибку

Самый быстрый способ сгенерировать тесты — дать агенту функцию и попросить покрыть её тестами. Агент прочитает код, увидит, что функция возвращает, и напишет тесты, которые это подтверждают. Если в функции ошибка, тест закрепит ошибку как правильное поведение.

Пример: функция группирует сделки по дате в UTC. Агент пишет тест «сделка в 23:40 по Москве попадает в следующие сутки» и тест проходит. Требование было обратным: группировать по местной дате клиента. Покрытие выросло, а ошибка стала частью тестовой базы.

Отсюда первое правило: тесты пишут от требований, а код используют только чтобы понять интерфейс.

Тесты от спеки

В spec-driven development каждый acceptance criterion связан с тестом. Порядок работы агента:

  1. Прочитать спеку и выписать критерии приёмки.
  2. Для каждого критерия написать тест, который его проверяет. Тест ссылается на номер критерия.
  3. Запустить тесты до реализации. Новые тесты должны падать.
  4. Написать реализацию, пока тесты не пройдут.

Шаг 3 важнее, чем кажется. Тест, который проходит до реализации, ничего не проверяет. Его стоит переписать.

Пример теста, привязанного к критерию:

// AC-1: сделка в 23:40 по местному времени клиента
// входит в отчёт за эти же сутки
test("AC-1: группировка по местной дате клиента", () => {
  const client = { id: "c1", tz: "Europe/Moscow" };
  const deal = { clientId: "c1", amount: "1000.00",
                 createdAt: "2026-03-14T20:40:00Z" }; // 23:40 МСК

  const report = buildDailyReport([deal], client, "2026-03-14");

  expect(report.total).toBe("1000.00");
});

Фильтр для сгенерированных тестов

В Meta описали инструмент TestGen-LLM, который улучшал существующие тесты, написанные людьми. Каждый сгенерированный тест проходил фильтр: собирается, стабильно проходит при повторных запусках, увеличивает покрытие. До инженеров доходили только тесты, которые прошли все три шага.

На продуктах Instagram результат был таким: 75% тестов собрались, 57% стабильно прошли, 25% увеличили покрытие. На тест-а-тонах в Instagram и Facebook инженеры приняли в production 73% предложений инструмента. Цифры показывают масштаб отсева: покрытие добавила только четверть сгенерированных тестов. Без автоматического фильтра остальные три четверти пришлось бы отсеивать человеку.

Фильтр стоит встроить в процесс генерации:

ПроверкаЧто отсеивает
Тест собирается и запускаетсяГаллюцинации API, неверные импорты
Тест проходит 5–10 запусков подрядНестабильные тесты: время, порядок, сеть
Тест добавляет покрытие строк или ветокДубли существующих тестов
Тест падает на мутанте кодаТесты без проверок или со слабыми проверками
Тест ссылается на требованиеТесты, которые закрепляют текущее поведение без основания

Мутационное тестирование как проверка тестов

Покрытие показывает, какой код выполнялся во время тестов. Оно не показывает, проверили ли тесты результат. Тест без единой проверки даёт покрытие так же, как хороший тест.

Мутационное тестирование вносит в код мелкие изменения: заменяет < на <=, убирает вызов, меняет константу. Хороший набор тестов ловит такие мутанты. Если мутант выжил, в этом месте тесты ничего не проверяют.

Инструменты: Stryker для JavaScript, TypeScript и C#, PIT для Java, mutmut для Python. Прогон по всей кодовой базе долгий, поэтому в процессе с агентами его запускают на изменённых файлах в MR. Выжившие мутанты агент получает как задачу: дописать проверки.

Как не дать агенту ослабить тесты

Если тест мешает агенту закончить задачу, агент может его поправить: ослабить проверку, пометить как пропущенный, удалить. Иногда он делает это открыто, иногда тест незаметно меняется в том же диффе.

Защита строится на нескольких уровнях:

  • Правило в AGENTS.md. «Не меняй и не отключай существующие тесты, чтобы они прошли. Если тест противоречит задаче, остановись и опиши в MR».
  • Проверка в CI. Изменения в существующих тестах, новые skip и only помечают MR для ревью человеком.
  • Правило ревьюера. Агент-ревьюер считает изменение существующих тестов без объяснения блокирующим замечанием. Подробнее — в статье про AI code review.
  • Владельцы тестов. Критичные наборы тестов закреплены за владельцами через CODEOWNERS.

Тесты для старого кода без требований

В старом коде спеки часто нет, а тесты нужны перед рефакторингом. Здесь задача обратная: зафиксировать текущее поведение, чтобы рефакторинг его не изменил. Такие тесты называют характеризационными.

  1. Агент пишет тесты на текущее поведение и явно помечает их как характеризационные.
  2. Человек просматривает тесты и отмечает поведение, которое выглядит ошибкой. Эти случаи заводятся отдельными задачами.
  3. Агент проводит рефакторинг, характеризационные тесты должны остаться зелёными.
  4. По итогам для модуля пишется спека, и тесты постепенно переводятся на требования.

Какие тесты агент пишет хорошо, а какие хуже

  • Хорошо: модульные тесты на чистые функции, таблицы граничных значений, тесты контрактов API по схеме, тесты на разбор и сериализацию данных.
  • Нужен контроль: интеграционные тесты с базой и очередями, где агенту нужно понимать окружение; тесты с моками, где легко замокать проверяемое поведение.
  • Хуже: end-to-end тесты интерфейса без описанных сценариев, нагрузочные тесты, тесты, которые зависят от знания продукта.

Тестирование в программе Праксора

Acceptance criteria в спеках привязываем к тестам, чтобы агент не достраивал предположения молча. Quality gates проверяют тесты так же строго, как код. Слои Harness

Вопросы

Можно ли доверять тестам, которые сгенерировал ИИ?

Доверять можно тестам, которые прошли фильтр: собираются, стабильно проходят, ловят мутации кода и проверяют записанные требования. Тесты, написанные по коду без требований, часто закрепляют ошибки.

Растёт ли качество от роста покрытия тестами ИИ?

Не обязательно. Покрытие показывает, какой код выполнился. Проверил ли тест результат, оно не показывает. Качество тестов лучше проверять мутационным тестированием и долей дефектов, которые тесты поймали до production.

Что делать, если агент меняет тесты, чтобы они прошли?

Запретить это в правилах агента, помечать изменения существующих тестов в CI для ревью человеком и сделать такое изменение блокирующим замечанием для агента-ревьюера.

Какие тесты лучше всего генерировать с помощью ИИ?

Модульные тесты на чистые функции, граничные значения, контракты API и сериализацию данных. Интеграционные и end-to-end тесты требуют описанных сценариев и контроля человека.

Начнём с разговора о вашей команде

На первом созвоне разбираем, как сейчас устроена постановка задач и разработка, где AI уже используется, и что можно измерить. После созвона будет понятно, какой Harness собирать и с какой команды начать.

Созвон 45 минут, без обязательств
Отвечает один из основателей
Можно под NDA
Оставить заявку
Что вам нужно
Отправляя форму, вы соглашаетесь на обработку контактных данных для связи по вашему запросу.