В последнее время вокруг систем ИИ, генерирующих тесты, активно развивается дискуссия, причем как в профессиональной, так и в академической среде. С одной стороны, такие системы делают ровно то, для чего задуманы ИИ-агенты: выполняют работу, которую мало кто любит делать, экономят массу времени и сил. С другой — порой выдают непредсказуемый результат: удаляют или корректируют тест-кейсы, игнорируют пограничные сценарии.
Мы решили посмотреть, какие мнения есть относительно генеративных тестов в ИТ-индустрии, и что говорит на их счет наука — разобрали свежие исследования по теме. А в конце статьи сделали подборку из открытых инструментов, которые помогут оценить возможности пары «нейросеть + юнит-тесты» самостоятельно.

Юнит-тесты + ИИ: что об этой связке думают в индустрии
Многие разработчики не любят писать тесты — и высказываются по этому поводу довольно категорично. Еще в 2014 году известный ученый в области программной инженерии и эксперт по языку C++ Джеймс Коплиен опубликовал статью, в которой называл юнит-тесты «бесполезной тратой [времени и сил]». Прохладное отношение разработчиков к модульным тестам обсуждали даже здесь на Хабре. Сегодня настроения в индустрии остаются похожими: по некоторым оценкам, от 40 до 50% разработчиков предпочли бы не писать тесты вовсе.
Один из вариантов решения проблемы — генерировать юнит-тесты с помощью ИИ. Быстро, удобно: нейросеть за считаные минуты покрывает ими весь код. Но отношение к такой практике среди разработчиков, мягко говоря, неоднозначное. С одной стороны, модульные тесты, сгенерированные с помощью ИИ-агентов, конечно, экономят время. Для крупных компаний эта экономия может достигать сотен человеко-часов. Например, в Goldman Sachs использовали инструмент Diffblue Cover, который пишет юнит-тесты на Java. С его помощью инженеры за сутки оформили 3,2 тыс. тестов для бэкенд-приложения из 15 тыс. строк кода — по оценкам компании, без системы ИИ на такую задачу ушли бы 268 рабочих дней.
С другой стороны, генерация модульных тестов имеет недостатки. Часть из них проявляется сразу, часть — по мере сопровождения проекта, многие носят системный характер и не зависят от используемых моделей. Обычно недовольство касается того, что ИИ-агенты:
Могут закреплять баги в коде как «корректное поведение». Если тесты пишутся на основе готового кода, модель может проверять, что функция делает сейчас, а не то, что ей положено делать. Разработчик из GitHub и Ph.D. в области компьютерных наук Дэвид Адамо-младший в своем блоге называет это «самосбывающимся пророчеством»: агент смотрит на сигнатуры и имена переменных, угадывает ветвления и подгоняет тест-кейсы под текущий результат.
Могут пропускать пограничные сценарии. Как следствие, сгенерированные тесты могут покрывать только типовые значения и игнорировать кейсы с переполнением, гонками, не учитывать редкие ошибки и таймауты. Кроме того, языковые модели склонны к галлюцинациям: обращаются к несуществующим методам, полям и сигнатурам, что ведет к некомпилируемым тестам.
Могут «подгонять» код тестов под текущую реализацию программы. За нейросетями замечена склонность решать задачу любой ценой — и в разработке это проявляется особенно наглядно. Столкнувшись с падающим тестом или сложным рефакторингом, агенты нередко удаляют тестовые файлы или вырезают отдельные проверки. В итоге сборка проходит без ошибок, но проблема в коде остается — и если разработчик привык доверять агенту, узнать о ней он может уже в продакшене.
Этот кейс куда более распространен, чем может показаться на первый взгляд. Джин Ким, автор книги «Проект "Феникс"» и экс-разработчик Google, рассказывал, как сталкивался с нейросетями, которые втихую правили «падающие» тесты, лишь бы они прошли — однажды агент удалил 80% тест-кейсов из набора. А в прошлогоднем интервью для площадки The Pragmatic Engineer создатель методологий разработки XP и TDD Кент Бек жаловался, что не может отучить ИИ-агентов удалять отдельные тестовые сценарии ради успешного прогона.
Что говорят исследования
Тема юнит-тестов и их генерации привлекает и внимание исследователей. За последние годы вышло большое количество научных работ, авторы которых стремятся систематизировать преимущества и недостатки подобного подхода — и, в отличие от Джина Кима и Кента Бека, они высказываются не так категорично. Вот, к каким результатам приходят в недавних публикациях:
Генеративные тесты действительно могут закреплять баги в коде, но масштаб проблемы не так уж велик: исследование Университета Торонто
Летом этого года группа исследователей из Университета Торонто представила работу, в которой решила оценить, насколько сильно качество кода и наличие в нем ошибок влияет на способность ИИ-агентов генерировать корректные тесты. Для этого они взяли бенчмарк Defects4J, содержащий сотни реальных ошибок из крупных проектов на языке Java. В наборе они представлены парами: версия кода с дефектом и версия, исправленная разработчиками.
Одиннадцати моделям от Google, OpenAI, Anthropic, xAI, DeepSeek и Alibaba показывали ошибочный вариант метода и просили написать юнит-тесты, а затем прогоняли их на сломанной и на корректной версиях. Если тест проходил на коде с дефектом, но падал на исправленном, значит, модель посчитала баг за ожидаемое поведение, а если наоборот — тест свою работу выполнял и считался корректным. Оказалось, что модели закрепляли ошибку в 3,84% тестов.
Хотя авторам исследования удалось немного сократить и эту цифру. Они предложили разорвать связь между тестом и реализацией: модель просили описать, что должен делать конкретный метод, и оформить это описание в docstring, а затем исходный код убирали из промпта. Когда модель писала юнит-тест на основе описания docstring, доля тестов, закрепляющих баг, снизилась с 3,84 до 2,69%.
В сгенерированных тестах наблюдается эффект «test smells» : результаты анализа 20 тыс. тестовых наборов
Существует понятие code smells — недостатки в программе, которые ухудшают ее читаемость и поддерживаемость. Это могут быть раздутые методы на сотни строк, дублирование, классы, которые делают все и сразу. По аналогии применяют термин test smells — признаки глубоких проблем в архитектуре или логике тестов. Недавно исследователи из Люксембурга, Китая, Сингапура и Турции задались вопросом: насколько ярко выражены подобные паттерны в тестах, генерируемых нейросетями, и насколько сильно их проявление зависит от промпта.
Команда проанализировала больше 20 тыс. тестовых наборов, написанных четырьмя ИИ-системами на базе нескольких Java-бенчмарков. Чтобы выявить проблемы, специалисты использовали инструменты TsDetect и JNose. В ходе эксперимента они также проверили, как на количество этих проблем влияют характеристики кода (объем, цикломатическая сложность, связанность классов) и параметры генерации (размер модели, длина контекстного окна, настройки семплирования).
Выяснилось, что чем крупнее проект, тем больше в тестах избыточных и поверхностных проверок. Что касается конкретных ошибок, то в сгенерированных тестовых наборах чаще всего встречалась проблема с assertion roulette, когда в одном тестовом методе находится много проверок assert без текстовых описаний. Так, если тест «падает», становится трудно понять, какая именно проверка не прошла.
Также специалисты отметили, что по какой-то причине агенты почти не покрывают тестами обработку исключений: у классического генератора EvoSuite (он использует эволюционные алгоритмы) этот показатель доходит до 93%, у нейросетей же держится в пределах 7–23%. Но даже если обойти эти моменты с помощью промптов, могут появляться и другие проблемы — например, дублирование проверок. В итоге исследователи пришли к выводу, что на данном этапе к сгенерированным тестам стоит относиться как к черновикам, требующим правок со стороны разработчика.

Несколько более оптимистичны швейцарские ученые — по их мнению, чтобы писать тесты, не всегда нужен даже узкоспециализированный агент (хотя и в этом исследовании результаты работы ИИ оказались довольно скромными):
ИИ-агенты, заточенные под написание кода, могут писать качественные тесты — исследование ETH Zurich
Специалисты из Швейцарской высшей технической школы Цюриха и компании по разработке ПО LogicStar проверили, насколько хорошо ИИ-агенты превращают оформленный GitHub issue в готовый тест-кейс. Для этого они собрали собственный Python-бенчмарк SWT-Bench почти из двух тысяч задач, построенных на основе 90 тыс. пул-реквестов из 12 популярных open source-репозиториев на GitHub.
Далее агентов, в первую очередь предназначенных для исправления ошибок в коде (SWE-agent, Aider и AutoCodeRover), попросили написать юнит-тесты, покрывающие проблему, просто изменив формулировку в промпте. Критерий успеха был простым: сгенерированный тест должен падать на исходном коде и проходить после применения эталонного исправления. Специалисты пришли к выводу, что системы ИИ, которые самостоятельно находят проблемные места в коде и пишут патчи с исправлениями, могут превосходить по эффективности узкоспециализированных агентов для генерации юнит-тестов — таких как LIBRO. LIBRO справился с 14,1% задач, а обычный SWE-agent — с 15,9%.
Какой подход выбрали мы в Далее
Итак, по мнению ученых, работать с генеративными тестами сложно, но можно. Справедливости ради, многие разработчики (как, например, программист и писатель Марк Земан) тоже не призывают полностью отказаться от ИИ-агентов для генерации тестов и предлагают приемы, которые могут улучшить результат:
Можно развести роли по разным агентам: один пишет код, а второй, который никогда не «видел» исходники, — готовит тесты. Суть подхода заключается в том, чтобы системы ИИ не делили одно рабочее пространство и не подтверждали сделанные в коде ошибки.
Использовать мутационное тестирование: внести в код намеренный баг, похожий на типичную ошибку, и посмотреть, поймает ли его сгенерированный набор тестов.
Мы в Далее тоже относимся к генеративным тестам с должной осмотрительностью — но не отказываемся от них полностью:
В настоящее время мы находимся на этапе пилотного внедрения: ИИ используется при написании тест-кейсов, но в ограниченной роли — как инструмент оформления и как «второй взгляд», способный предложить негативные сценарии, которые можно упустить при ручной проработке.

Влад Голодников
руководитель отдела QA в Далее
Наш подход. Мы задаём агенту контекст проекта и суть проверяемой функциональности, а также логику, которую закладываем сами. На выходе получаем корректно оформленный тест-кейс, соответствующий заданной логике [формализованного регламента для проверки генеративных тестов у нас нет, проверка встроена в общий процесс ревью и не выделяется в самостоятельную процедуру]. Полностью автоматическая генерация кейсов без предварительного погружения модели в контекст проекта показывает посредственное качество, поэтому мы её не применяем.
Отдельно стоит отметить работу с чек-листами: здесь ИИ показывает себя достаточно хорошо и, как правило, покрывает большую часть необходимых и значимых проверок.
Плюсы:
Быстрое и аккуратное оформление тест-кейсов по заданной логике — экономия времени на рутинной части.
Генерация негативных сценариев, которые могут быть упущены при ручной проработке.
Высокое качество формируемых чек-листов с покрытием основных проверок.
Минусы:
Качество автоматически сгенерированных кейсов заметно падает без достаточного контекста проекта.
Верификация и правка результата в ряде случаев занимает больше времени, чем самостоятельное написание кейса с нуля.
Сохраняется необходимость экспертного контроля: результат нельзя принимать без ревью.
Так что на текущий момент ИИ рассматривается нами не как замена ручному проектированию тестов, а как вспомогательный инструмент для ускорения оформления и расширения покрытия сценариев. И учитывая, что текстовый контент сейчас все чаще создается с использованием ИИ (и код — как частный случай — не исключение), дискуссия о том, применять или не применять ИИ-агентов для его генерации уже несостоятельна — вопрос не в том, кто автор, а в том, насколько хорош результат:
Пытаться выявлять и целенаправленно устранять признаки генеративного происхождения материала, будь то новость, пост или юнит-тест, на мой взгляд, не имеет практического смысла — это борьба со следствием, а не с сутью.
В обозримой перспективе генеративный контент в самом широком смысле станет отраслевой нормой, а полностью ручное написание перейдёт в категорию скорее ремесленного или авторского подхода, чем повседневной практики.
Соответственно, фокус проверки, с моей точки зрения, должен смещаться с вопроса «как это было написано» на вопрос «насколько это корректно, полно и применимо». Оценивать имеет смысл содержательное качество — покрытие, корректность логики, соответствие требованиям, а не происхождение формулировок.

Влад Голодников
руководитель отдела QA в Далее
На чем потестить юнит-тесты: открытые ИИ-агенты
Для тех, кто хочет составить собственное мнение об эффективности генеративных тестов, мы собрали подборку профильных инструментов.
Test Generator Agent — агент-полиглот от Microsoft для генерации юнит-тестов. Он работает с C#, Python, Go, TypeScript, Java, Rust и другими языками. Инструмент не просто пишет тесты, а проверяет их состоятельность — качество утверждений (assertions) и покрытие запрошенных сценариев. В первую очередь он изучает репозиторий: ищет код без тестового покрытия, определяет язык и разбирает уже существующие тесты, чтобы понять, где они лежат и как должны выглядеть — только после этого он планирует, готовит и проверяет собственные.
Разработчики провели несколько экспериментов, в том числе использовали задачи по написанию юнит-тестов из набора SWE Atlas, который считается довольно сложным. Специализированный агент прошел на четыре задачи больше, чем стоковый Copilot на той же модели и с теми же промптами.
Агент, скиллы и языковые расширения открыты под MIT и лежат в репозитории dotnet/skills. Чтобы начать работу, достаточно выбрать code-testing-generator из списка агентов и прописать простой промпт: Generate unit tests.
Qodo Cover — инструмент для автоматической генерации тестов, который может работать как в GitHub CI, так и локально в виде CLI-утилиты. Исходники открыты под лицензией AGPL 3.0. Система состоит из четырех компонентов:
Test Runner — запускает скрипты тестового набора и собирает отчеты о покрытии кода тестами.
Coverage Parser — проверяет, что новые тесты не бесполезны, а покрытие растет.
Prompt Builder — собирает данные из кодовой базы и формирует промпт для языковой модели.
AI Caller — обращается к модели и получает сгенерированные тесты.
Также Qodo Cover прогоняет все тесты по пять раз, чтобы выявить «мигающие», которые то проходят, то падают, при неизменном коде.
К сожалению, при всех достоинствах проекта, у него есть минус: разработчики не планируют поддерживать репозиторий, поэтому желающим продолжить разработку или использовать код в своих проектах, предлагают его форкнуть.
Наконец, в качестве бонуса, — чисто детерминированный статический анализатор для поиска «запахов» в тестах Java-проектов, под названием Test Smell Detector. Он вырос из академического проекта в Рочестерском технологическом институте. Команда отмечала, что открытых детекторов с широким охватом типов и поддержкой CI не хватало. Тогда специалисты решили сделать свой собственный и передать его в open source под лицензией GPL 3.0. И именно его использовали ученые из приведенного выше исследования про test smells.
Какой бы инструмент вы ни выбрали, основную ценность в итоговый результат будет привносить человек и его квалификация:
На горизонте ближайших пары лет, с учётом текущих темпов развития ИИ, я ожидаю, что значительная часть задач разработки и тестирования будет закрываться средствами ИИ. Появление у моделей возможностей работы с визуальным контекстом (vision) уже сегодня заметно повышает их прикладную ценность — ИИ становится действительно полезным помощником, а не только генератором текста.
При этом ключевым фактором остаётся не сам инструмент, а квалификация специалиста, который им управляет. Поэтому в первую очередь я бы рекомендовал уделять внимание не конкретным продуктам, а фундаментальной базе:
Архитектура систем — понимание того, как устроено приложение, позволяет корректно формулировать задачу и оценивать адекватность полученного результата;
Алгоритмы и основы разработки — без этого невозможно объективно верифицировать то, что предлагает модель;
Методология тестирования — понимание, что и почему проверяется, остаётся зоной ответственности человека.
Эта база даёт возможность точно объяснить ИИ, что именно требуется сделать, каким образом и что является критически важным в конкретном контексте, а также самостоятельно оценить качество результата.
Что касается инструментов — сейчас имеет смысл в рабочем режиме осваивать ИИ-ассистентов (как в связке с IDE, так и в формате агентов), включая работу с визуальным контекстом, и вырабатывать навык качественной постановки задачи. Но рассматривать их стоит именно как усилитель собственной экспертизы: чем глубже понимание того, как система разрабатывалась и тестировалась, тем выше отдача от использования ИИ.

Влад Голодников
руководитель отдела QA в Далее
Уже используете генеративные тесты — или считаете, что пока ИИ-агентам эта задача не по зубам? Поделитесь вашим опытом в комментариях.