Как мы заставили ИИ писать тесты для ИБ-проекта

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

Расскажу, как это выглядело на практике.

Шаг 1. Выбрали модель

Взяли локальную модель. Не хотели гонять данные через внешние API. Поставили на отдельный сервер с GPU. Модель среднего размера, но с хорошим пониманием Python и REST, curl.

Первая неделя — разочарование. Модель выдавала синтаксически верные тесты, но логически пустые. Она не понимала контекста безопасности.

Шаг 2. Собрали контекст

Поняли: нужен чёткий каркас Harness обёртка. Мы описали всю архитектуру в одном документе. Схему базы данных. Формат запросов и ответов. Ожидаемые коды ошибок. Правила авторизации: какие токены нужны, как они проверяются, сроки действия.

Каждый тест мы снабжали примером. Входные данные, ожидаемый вывод, граничные значения.

Шаг 3. Настроили промпт-шаблон

Зафиксировали структуру запроса.

1. Роль: «Ты — QA-инженер по безопасности». 2. Спецификация эндпоинта. 3. Пример тела запроса. 4. Пример успешного ответа. 5. Примеры ошибочных сценариев (пустые поля, неверный токен, просроченная сессия). 6. Требование: написать тест на pytest с использованием фикстур и моков.

С этим шаблоном качество выросло на порядок.

Шаг 4. Интеграция в CI

Не отдавали всё на откуп модели. Сделали пайплайн: сначала CI запускал уже готовые ручные тесты. Затем, по расписанию (раз в сутки), запускался генератор ИИ для новых эндпоинтов. Сгенерированные тесты падали в отдельную папку. Мы смотрели их вручную, правили и добавляли в основной набор.

Так мы не ломали работающую систему и одновременно наращивали покрытие.

Шаг 5. Детектор галлюцинаций

Модель иногда выдумывала несуществующие поля в JSON. Или использовала не те заголовки. Мы написали простой валидатор. Он прогонял сгенерированный тест без запуска — просто проверял синтаксис и наличие всех обязательных полей в спецификации. Если валидатор ругался, тест не добавлялся в очередь. Модель получала обратную связь: «Ошибка, поле token не найдено». На следующей итерации она исправлялась.

Шаг 6. Кейс: тестирование механизма шифрования

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

Мы дали модели описание алгоритма и несколько примеров. Она сгенерировала три теста: один успешный, два с ошибками (неверный ключ, повреждённое сообщение). Изменения потребовали минимальной правки — только поправили названия переменных под наши внутренние стандарты.

Шаг 7. Как мы решали проблему флаки

Первое время некоторые тесты падали случайно. Причина: ИИ использовал жёсткие временные метки, а на CI время могло отличаться на секунду. Мы добавили в промпт требование: использовать моки для времени через pytest-freezegun. После этого флаки исчезли.

Шаг 8. Результаты сейчас.

Покрытие тестами выросло с 40% до 65%. Время на написание новых тестов сократилось в 7 раз. Мы тратили около часа в день на ревью сгенерированного кода и его адаптацию. Остальное время освободилось для стратегических задач.

Шаг 9. Главный урок

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

Зеркало. Разрушаем стереотип

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

Инструмент — это всего лишь инструмент. Если вы управляете процессом, он работает на вас.

Как мы заставили ИИ писать тесты для ИБ-проекта | Сетка — социальная сеть от hh.ru