Генерация автотестов с ИИ: опыт, уроки и лучшие практики 2026 | AiManual
AiManual Logo Ai / Manual.
24 Июн 2026 Гайд

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

Реальный опыт пилота по внедрению ИИ для генерации автотестов: методики промптов, типичные ошибки, как не провалить старт. Практические советы для QA и DevOps.

Реклама
partv1

Две недели на первый PR — и это нормально

Когда я впервые попросил LLM (тогда это был GPT-4.5 Turbo, июнь 2025) написать тесты для модуля платежей, я ожидал магии. Через 15 минут я получил 200 строк прекрасного кода на Python с использованием pytest. Выглядело идеально. До первого запуска.

Тесты падали с ошибками, которые невозможно было воспроизвести. Моки не соответствовали реальным ответам API. А assertions проверяли то, что никому не нужно. Знакомо? Тот PR мы закрыли только через 14 дней. И дело не в ИИ — дело в подходе.

Эта статья — не очередной теоретический обзор. Это хроника внедрения ИИ-генерации тестов в продуктовую команду из 12 разработчиков и 4 QA. С кровью, потом и галлюцинациями. Я расскажу, что сработало, что нет, и как превратить LLM из дорогой игрушки в рабочую лошадку.

Ключевая мысль: ИИ не пишет хорошие тесты сам по себе. Он пишет тесты, которые соответствуют вашему промпту и контексту. Хороший тест — это результат хорошего промпта + качественного контекста + человеческой валидации.

Проблема: почему 95% пилотов превращаются в дорогой хлам

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

  • Иллюзия zero-shot. Скормить LLM файл с кодом и сказать "напиши тесты" — это как попросить незнакомца написать завещание. Модель не знает ваших бизнес-правил, конвенций именования, структуры проекта. Результат — бесполезный код.
  • Галлюцинации API. LLM обожает выдумывать методы и параметры. Если она "знает" библиотеку, но не видела ваш конкретный код, она сгенерирует вызовы, которые никогда не существовали. Подробнее об этом — в нашем аудите галлюцинаций LLM 2026.
  • Отсутствие итераций. Первый результат никогда не бывает финальным. Но многие останавливаются на первой попытке, разочаровываются и пишут статью "ИИ не работает".

Если вы узнали себя — вы не одиноки. Я тоже прошел через это. Как мы выкарабкались — читайте ниже.

Решение: трехслойная методика "Контекст-Промпт-Валидация"

После двух недель мучений мы выработали систему, которая сократила время генерации приемлемого теста до 30-40 минут (против 4-5 часов вручную). Система состоит из трех слоев.

1 Контекст: чем больше, тем лучше (но не спам)

LLM нужно дать не просто сигнатуру функции, а полную картину. В наш промпт мы включаем:

  • Исходный код тестируемого модуля (целиком, если возможно).
  • Схему базы данных или ER-диаграмму (текстовое описание).
  • Примеры успешных тестов из соседних модулей (1-2 файла).
  • Описание бизнес-логики: какие кейсы критичны, какие граничные значения важны.
  • Список зависимостей, которые нужно мокать, и ожидаемые ответы.

Звучит громоздко? Да. Но без этого модель будет гадать. Один из наших QA попробовал дать только код — получил тест, который проверял, что функция возвращает строку, хотя по спецификации должна возвращать словарь. ИИ просто "увидел" return "..." в примере и решил, что это всегда строка.

Кстати, о том, как правильно структурировать промпты, мы подробно разобрали в статье "Как заставить ИИ-ассистента для кода работать эффективнее". Там же — конкретные шаблоны.

2 Промпт: от новичка до сеньора за три уровня

Мы заметили, что качество тестов напрямую зависит от уровня детализации промпта. Я выделяю три уровня, которые описал в отдельной статье "Три уровня промптов для автотестов". Кратко:

  • Уровень 1 (новичок): "Напиши тесты для функции X". Результат — базовые юнит-тесты, часто с багами.
  • Уровень 2 (практик): "Напиши тесты для функции X с использованием pytest, моками для внешних вызовов, проверкой граничных значений". Уже лучше, но все еще не идеально.
  • Уровень 3 (сеньор): Полный контекст, примеры, описание expected behavior, чек-лист того, что проверять. Результат — тесты, которые покрывают 90% сценариев, включая негативные.

Мы используем Level 3 как базовый. Но даже на этом уровне нужна валидация.

3 Валидация: человек в цикле — не баг, а фича

ИИ генерирует, человек проверяет. Это не про недоверие — это про безопасность. Кейс с Франкфуртом отлично иллюстрирует, чем заканчивается слепая вера в ИИ. В тестировании цена ошибки — баг в проде.

Наша процедура валидации:

  1. Проверить, что тест действительно выполняется (зеленый прогон).
  2. Проверить, что тест ловит реальный баг (например, внести преднамеренную ошибку в код — тест должен упасть).
  3. Проверить, что тест не избыточен (не дублирует другие тесты).
  4. Проверить читаемость: названия переменных, комментарии, структуру.

Только после этого тест попадает в репозиторий. Звучит как лишняя работа, но на практике это занимает 5-10 минут на тест вместо часов написания.

Пошаговый план: от идеи до первого ИИ-теста за полчаса

Допустим, вы решили попробовать. Вот точная последовательность, которую мы нашли рабочей.

1 Выберите один модуль-пилот

Не пытайтесь автоматизировать всё сразу. Возьмите изолированный микросервис или класс с понятной логикой. Идеально — модуль, который уже покрыт ручными тестами, чтобы было с чем сравнивать. Это снизит риски, о которых мы писали в статье про провал 95% пилотов.

2 Подготовьте контекст-пакет

Соберите в один текстовый файл:

  • Код модуля.
  • Примеры вызовов (например, curl запросы или Python-скрипты).
  • Описание контракта (OpenAPI spec, proto-файлы).
  • 1-2 примера ваших лучших тестов (стиль, паттерны).

Этот файл будет служить "памятью" для LLM. Если используете RAG-систему — еще лучше. Мы в итоге перешли на локальную RAG-базу, что описано в материале "Автоматизация тестирования: как RAG + LLM генерируют Java-тесты в IDE".

3 Напишите промпт уровня "сеньор"

Вот реальный шаблон, который мы используем (анонимизирован):

Ты — senior QA engineer. Напиши pytest тесты для модуля payment_processor.py.

Контекст:
- Код модуля (см. ниже).
- База данных: таблицы users, orders, payments. Связи: orders.user_id -> users.id, payments.order_id -> orders.id.
- Внешние зависимости: Stripe API (мокать с помощью responses библиотеки).
- Пример успешного теста из соседнего модуля (см. ниже).

Требования к тестам:
1. Покрыть: успешный платеж, недостаточно средств, неверный токен, таймаут Stripe.
2. Использовать pytest fixtures, parametrize для граничных значений.
3. Названия тестов: test_<сценарий>_<ожидаемый_результат>.
4. Добавить assert на статус ответа, вызов мока, изменение БД.
5. Не использовать monkeypatch — только responses.

Вот код модуля:
[код]

Вот пример теста:
[пример]

Сгенерируй только код, без объяснений.

4 Запустите, отладьте, итерируйте

Первый результат почти всегда содержит ошибки. Скопируйте ошибку в новый промпт с просьбой исправить. Или поправьте вручную. Через 2-3 итерации тест становится рабочим. Не ждите идеала с первого раза.

5 Внедрите в CI/CD

Когда тесты готовы, добавьте их в пайплайн. Но сначала — код-ревью человеком. Мы используем правило: тест, сгенерированный ИИ, проходит такое же ревью, как и рукописный. Это снижает риск появления "мусорных" тестов, которые только увеличивают время прогона.

Уроки, которые мы выучили на своей шкуре

Урок 1: ИИ не понимает бизнес-контекста

Однажды LLM сгенерировал тест, который проверял, что после успешного платежа статус заказа меняется на "shipped". В реальности статус должен был стать "paid", а "shipped" выставляется только после отгрузки. Модель "додумала" логику. Мы потратили час на выяснение, что тест неправильный. Решение — всегда явно описывать ожидаемое поведение в промпте.

Урок 2: Размер контекста имеет значение

Современные модели поддерживают огромные окна (до 200k токенов). Но это не значит, что нужно пихать всё подряд. Мы заметили: чем больше контекста, тем выше вероятность, что модель "забудет" начало. Оптимальный объем — 10-15% от максимального окна. Структурируйте контекст: сначала самое важное (код), потом детали (схема БД), потом примеры.

Урок 3: Люди сопротивляются

Внедрение ИИ в тестирование — это не только техническая, но и социальная задача. QA-инженеры боятся, что их заменят. Разработчики не доверяют сгенерированным тестам. Мы прошли через это и написали отдельный материал: "Психология сопротивления ИИ: как работать с хейтерами". Кратко: покажите ценность на маленьком примере, обучите, дайте право голоса.

Урок 4: Безопасность и галлюцинации

LLM может сгенерировать тест, который использует несуществующие методы безопасности, или, того хуже, сохраняет чувствительные данные в логах. В нашем аудите галлюцинаций 2026 мы выяснили, что даже самые современные модели врут в 5-15% случаев. Для тестов это критично. Всегда проверяйте, что тест не использует секреты в открытом виде и не вызывает опасных операций (например, удаление данных).

Лучшие практики, которые мы наработали за 6 месяцев

  • Используйте версионирование промптов. Сохраняйте удачные промпты в git или Wiki. Это позволяет быстро адаптировать их для новых модулей.
  • Создайте библиотеку "золотых" тестов. 5-10 идеальных тестов, на которые LLM может ориентироваться как на пример стиля.
  • Не генерируйте всё сразу. Лучше по одному тесту на сценарий, чем 50 тестов с одинаковыми ошибками.
  • Интегрируйте объяснение решений. Используйте принципы Explainable AI, чтобы понимать, почему ИИ выбрал именно такой тест. Просите LLM комментировать свои решения.
  • Не забывайте про сдвиг влево (shift-left). Генерация тестов на этапе проектирования (по спецификациям) эффективнее, чем по готовому коду. Мы начали генерировать тесты параллельно с написанием кода — это сократило цикл обратной связи.

Типичные ошибки новичков (и как их избежать)

💡
Этот раздел — результат наших собственных граблей и наблюдений за коллегами.
  • Ошибка: давать модели слишком мало контекста. Исправление: используйте шаблон контекст-пакета выше.
  • Ошибка: верить первому результату. Исправление: всегда прогоняйте тест и проверяйте на баге.
  • Ошибка: не проверять негативные сценарии. LLM по умолчанию пишет happy path. В промпте явно указывайте: "напиши также тесты на ошибки: network timeout, invalid input, authentication failure".
  • Ошибка: забывать про производительность. Сгенерированные тесты могут быть медленными (например, использовать реальные вызовы API вместо моков). Указывайте в промпте требования к скорости.
  • Ошибка: игнорировать человеческий фактор. Если команда не готова, пилот провалится. Проведите обучение, сделайте демо, покажите, что ИИ — помощник, а не замена. Почитайте нашу статью про психологию сопротивления.

Что дальше? Прогнозы на 2026-2027

Мы уже сейчас видим, как ИИ переходит от генерации отдельных тестов к автономному исследованию приложений. Модели вроде Claude 4 Opus умеют запускать приложение, кликать по кнопкам и записывать тесты. Но пока это экзотика. Основной тренд — интеграция LLM в IDE (как в Cursor или Copilot) с возможностью вызывать модель прямо из кода. Мы уже используем это для рефакторинга тестов.

Еще одно направление — RAG-системы, которые хранят документацию, требования и историю багов. Вместо того чтобы пихать всё в промпт, модель обращается к векторной базе. Это снижает галлюцинации и ускоряет генерацию. Пример такой архитектуры для Java мы описали в статье "RAG + LLM генерируют Java-тесты".

Но есть и риски. Чем больше мы полагаемся на ИИ, тем больше атрофируются наши навыки написания тестов. Статья про автопилот в кодинге хорошо объясняет этот эффект. Мой совет: продолжайте писать тесты руками хотя бы для новых сценариев. ИИ — для рутины, человек — для творчества.

Важно: не пытайтесь автоматизировать всё. Если модуль меняется каждый спринт, ИИ-тесты будут устаревать быстрее, чем вы их проверите. Используйте ИИ для стабильных компонентов.

Помните: цель ИИ в тестировании — не заменить QA, а дать им время думать о сложных кейсах, а не писать boilerplate. Если ваша команда сейчас тратит 70% времени на написание тестов, а 30% — на анализ, наша методика может перевернуть пропорцию. Попробуйте — и пишите в комментариях, что получилось.

Подписаться на канал