Автогенерация тестов для Java/Kotlin в IntelliJ IDEA: сравнение AI-инструментов

от автора

Привет, Хабр! Для большинства разработчиков тесты – это нелюбимая часть работы. Недавно мы убедились в этом, опросив больше 400 разработчиков на конференциях Joker и Heisenbug об их отношении к AI-инструментам для тестирования. В статье расскажем, что еще интересного мы от них узнали, а также какие существуют AI-инструменты для автоматической генерации тестов, какие у них есть плюсы и минусы.

Почему никто не хочет писать тесты и причем здесь языковые модели

Итак, какие выводы нам помогли сделать участники Joker и Heisenbug. Во-первых, оказалось, что несмотря на то, что с появлением трансформеров у сообщества появился сильный инструмент для генерации кода, большая часть опрошенных не пользуется никакими AI-инструментами в повседневной работе:

Предполагаем, что это связано с требованиями безопасности. Много специалистов, с которыми нам удалось пообщаться, подтвердили, что без on-premise рассматривать AI-ассистентов они не готовы.

Во-вторых, по словам разработчиков, есть несколько основных проблемы с написанием тестов:

  • лень/долго/скучно (подавляющее большинство!)

  • одинаковая работа

  • сложно придумать много краевых случаев

  • сложно правильно мокировать зависимости

Если процесс однообразен и скучен, стоит подумать о его автоматизации. Проблема автогенерации тестов существует очень давно, стандартно её решали с помощью генерации шаблонов тестов, property-based тестинга, фаззинга и символьного исполнения. Первые два подхода вынуждают частично писать тесты вручную, например, придумывать тестовые данные или свойства. Последние два подхода порождают нечитаемые тесты, которые тяжело поддерживать. Так, например, хотя символьное исполнение способно создать 5 тысяч тестов со стопроцентным покрытием, но читать и поддерживать их в перспективе совершенно невозможно.

Таким образом, идеальный тестовый инструмент:

  • делает рутинную работу за разработчика

  • экономит время разработчика на придумывание корнер-кейсов

  • понимает контекст кодовой базы

  • генерирует поддерживаемые человеко-читаемые тесты

  • помогает в мокировании

Благодаря ChatGPT появился новый перспективный способ генерации тестов при помощи языковой модели: скопируй свой код в ChatGPT, попроси тесты и она тебе их сгенерирует.

Зачем вообще нужны специализированные плагины для генерации тестов?

Строго говоря, для генерации тестов плагин не требуется. Можно воспользоваться подпиской на одну из моделей и посылать запросы для генерации прямо в веб-чате chatgpt.com. Существует множество плагинов, которые интегрируют чат в IDE, например, Codeium, или дополняют код, как GitHub Copilot. Почему не использовать их и для генерации тестов?

Ключевая проблема – сбор кодового контекста. Если дать LLM только код функции без её зависимостей, странно ожидать, что получатся хорошие тесты или что они хотя бы будут компилироваться (представьте, что вам дали незнакомую кодовую базу, запретили в нее заглядывать и попросили написать тест для случайной функции). Указывать вручную все зависимости – также рутинная механическая работа. Значит хороший плагин для генерации тестов должен автоматически собирать разумные зависимости в промпт.

Очень важной частью взаимодействия с LLM являются промпты (описание задачи для LLM на естественном языке). От качества промпта зависит качество сгенерированных тестов: их компилируемость, соответствие стилю кодовой базы, какое эти тесты будут давать тестовое покрытие. Составить такой промпт качественно – трудоемкая задача. Получается, что монотонную задачу написания тестов разработчик заменяет на задачу исправления и переписывания промпта. LLM-плагины для тестогенерации стараются оградить пользователя от этого кошмара, предлагая готовые пайплайны для разных случаев генерации с уже «зашитыми внутрь» промптами для разных юзкейсов.

Зачем нужны специализированные плагины для генерации тестов, если собирать контекст и использовать заточенные под задачу промпты могут AI-ассистенты для генерации кода, такие как Codeium, Cursor, Gigacode? Их возможности шире, но менее специфичны с точки зрения пользовательского опыта: плагин должен не только автоматически генерировать код, но и интегрироваться с существующей кодовой базой. Например, он должен определять версию языка, build систему (Maven, gradle, Kotlin gradle), моковый фреймворк (mockito или mockk), тестовую библиотеку (ktest, junit, TestNG), стиль используемых в проекте тестов и так далее. Если всё это нужно указывать в промпте вручную, то уже нет особой разницы, генерируешь тесты при помощи chatgpt.com или Codeium.

☝️🤓: Несмотря на очевидный плюс – понимание контекста – у языковых моделей есть недостатки. Так, вы не можете гарантировать, что код, который выдаст LLM, будет компилироваться и запускаться. А еще каждый из существующих LLM-инструментов оперирует так называемым «семантическим покрытием», а не реальным покрытием инструкций, поэтому, вообще говоря, у вас нет строгих гарантий, что с увеличением количества LLM-тестов, покрытие инструкций будет увеличиваться.

Какой выбрать?

Чтобы оценить преимущества специализированных плагинов для тестогенерации, имеет смысл сравнить их между собой. 

Для анализа мы рассмотрим Tabnine, Qodo, Explyt Test и TestSpark, а также упомянем Diffblue Cover, который представляет подход на основе ML без использования LLM. Codeium, GigaCode будут выступать в качестве альтернативы специализированным подходам.

Какие плагины мы будем сравнивать?

Я уже говорил, что для генерации тестов можно использовать AI-ассистента, который может работать с контекстом проекта. Для сравнения со специализированными инструментами возьмем два таких продукта: Codeium и GigaCode.

Типичные инструменты для генерации тестов с помощью LLM – Tabnine, Qodo, Explyt Test. Языковые модели позволяют быстро генерировать код на любом языке, UI и двухфазная генерация (тестовые сценарии, затем код) позволяют управлять corner-кейсами. Другой LLM-инструмент – TestSpark, плагин для генерации тестов на java и kotlin, в отличие от Tabnine и Codium пропускает генерацию сценариев, зато позволяет редактировать код каждого теста прямо в окне генерации и имеет открытый исходный код.

Существуют также решения на основе ML, но без использования LLM, например, Diffblue Cover. Утверждается, что сгенерированные им тесты, в отличие от тестов, сгенерированных LLM-инструментами, всегда компилируются и запускаются.

Сравнение

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

Qodo Gen

Qodo Gen
Tabnine

Tabnine
Explyt Test

Explyt Test

Что их тогда друг от друга отличает?

Какие уникальные фичи есть у этих плагинов?

Автоматическое исправление некомпилирующихся и падающих тестов

Frontier-языковые модели умеют классифицировать возникающие проблемы и предлагать для них решения «из коробки». Удобно, когда в плагине для генерации тестов есть кнопка, позволяющая автоматически исправить тест при помощи языковой модели.

Создание автофиксов – следствие неспособности LLM генерировать компилирующийся код, правильно импортировать зависимости. Об этих и других проблемах мы рассказали на JokerConf.

Использование своего LLM-ключа

Если у вас уже есть личный или корпоративный ключ от какого-либо провайдера, очень удобно, когда плагин для генерации тестов позволяет использовать его и взаимодействовать с провайдером напрямую.

Настройка провайдера и модели

В языковых моделях идёт гонка вооружений, и модели OpenAI устраивают не всех. Хорошо, когда плагин генерации тестов даёт возможность поменять провайдера и модель, чтобы лучше подходить вашему сценарию использования. Например, DeepSeek стоит значительно дешевле, чем топ-провайдеры, Groq генерирует тысячи токенов/сек, пока остальные измеряют скорость генерации в сотнях токенов/сек.

Дообучение модели для своей кодовой базы

Дообучение (fine-tuning) – процесс адаптации модели для конкретной задачи. Некоторые плагины позволяют дообучать языковые модели на вашей кодовой базе, чтобы улучшить качество генерации. Согласно Codeium, дообучение позволяет сильно улучшить качество предлагаемого AI-ассистентом кода

Codeium

Codeium

☝️🤓:  Стоит заметить, что дообучение в закрытом контуре – сложная задача и, возможно, игра не стоит свеч. Эффект дообучения сильно зависит от качества данных и само дообучение сложно автоматизировать.

Использование локально развёрнутой модели

Иногда хочется, чтобы код не уходил в интернет, или к интернету просто нет доступа (например, в самолете). Если компьютер достаточно мощный, на нём можно разместить достаточно большую языковую модель, которая будет генерировать осмысленный код. Для этого существует, например, проект Ollama, позволяющий развернуть локально любую модель с открытыми весами. Хорошо, если плагин для генерации тестов поддерживает возможность использовать локально развёрнутую модель.

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

Для удобства, свели все рассмотренные атрибуты для всех решений в одну табличку. Так как Diffblue Cover работает на базе RL, а не языковых моделей, параметры, связанные с LLM, к нему неприменимы. В Diffblue не поддержана починка тестов, нельзя выбрать ML-модель для генерации, нельзя ее дообучать. Также Diffblue Cover работает исключительно локально, хотя и требует подключения к интернету для всех тарифов кроме Enterprise.

Плагин

Автофикс тестов

Свой LLM-ключ

Выбор провайдера и модели

Дообучение

Локальный хостинг

Codeium

нет

нет

да

да

нет

GigaCode

нет

нет

нет

нет

нет

Tabnine

нет (для jvm)

да (enterprise)

Tabnine, OpenAI, Claude

да (enterprise)

нет

Qodo

нет (для jvm)

нет

OpenAI, Claude, Gemini

нет

нет

TestSpark

да

да

HuggingFace, OpenAI

нет

нет

Diffblue Cover

нет

работает только
локально

Explyt Test

да, но только для LLM-тестов (compile + runtime)

да

OpenAI, Claude, Gemini, DeepSeek, Groq, Cerebras, Anthropic

нет

да

Как плагины работают с контекстом проекта?

Правильный подбор контекста очень важен для получения качественных результатов от LLM.

Есть несколько способов собирать кодовый контекст. Более простым является эвристический, как, например, в GitHub Copilot: анализировать три последних открытых файла. Для генерации тестов такие эвристики плохо подходят, так как нужен специализированный алгоритм именно для генерации тестов. Хотя большинство AI-ассистентов требуют собирать контекст руками, для задачи генерации тестов может быть реализован автоматический сбор контекста.

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

Часто на работу кода влияет и не кодовый контекст. Он может включать файлы конфигураций приложения, не содержащие код, но важные для понимания контекста работы тестируемого приложения. Примеры не кодового контекста – xml-файл со Spring-конфигурацией бинов, env-файл с переменными окружения.

Плагин

Контекст

Использование похожего теста

Не кодовый контекст

Codeium

авто+руками

руками

нет информации

GigaCode

выделение или текущий файл

руками

нет информации

Tabnine

авто+руками

руками

нет информации

Qodo

авто+руками

руками

нет информации

TestSpark

авто

руками

нет информации

Diffblue Cover

авто

нет

нет информации

Explyt Test

авто

авто

в разработке

Что если важно, на какие сервера отправляется код?

Хотя существуют бесплатные чат-провайдеры и инструменты для генерации кода, наши опросы показывают, что подавляющее большинство специалистов AI-инструментами вообще не пользуется. На вопрос «почему?» обычно отвечают, что это запрещено политикой компании из-за требований безопасности: исходный код не должен выходить из контура компании, использовать инструменты с чужим хостингом запрещено. Но все-таки, если использовать инструмент очень хочется, можно выбрать хостинг, отвечающий вашим требованиям приватности:

  • Community. Ваши запросы отправляются на сервер провайдера LLM. В зависимости от выбранного плана, провайдер может обещать не использовать ваши данные для обучения моделей или предоставлять opt-out (так делает Qodo, для бесплатной версии предоставляет opt-out). У некоторых провайдеров (например, Tabnine) можно запросить zero data retention: данные вашего запроса не будут сохраняться на серверах вообще.

  • (Virtual) Private Cloud ((V)PC). Вы используете инфраструктуру облачного провайдера, при этом удаленный доступ к ней есть только у вас. Такой сервис предоставляет, например, Amazon, Yandex, cloud.ru от Сбера. 

  • On-premise hosting. Вы полностью управляете инфраструктурой, на которой разворачивается решение, так как используются ваши сервера или сервера, к которым у вас есть доступ.

Для международной сертификации ПО на безопасность используется протокол SOC 2. Если вкратце, то SOC 2-аттестованный поставщик SaaS-продукта отвечает пяти критериям: безопасность (защита от неавторизованного доступа), доступность (обеспечение доступности услуг согласно соглашениям), целостность обработки (точность и авторизация данных), конфиденциальность (ограничение доступа к данным), приватность (соблюдение политики обработки персональной информации). В РФ есть свой аналог – аттестация ФСТЭК, требования которой в целом похожи на SOC 2. Ни один из зарубежных плагинов аттестацию ФСТЭК, разумеется, не прошёл.

Плагин

Опции приватного хостинга

Сертификации

Аттестация ФСТЭК

Codeium

on-prem (enterprise)

SOC 2

нет

GigaCode

on-prem

нет

да

Tabnine

on-prem (enterprise)

GDPR, SOC 2

нет

Qodo

on-prem (enterprise)

SOC 2

нет

TestSpark

недоступно

нет

нет

Diffblue Cover

запускается только локально

нет

Explyt Test

on-prem (enterprise)

планируется SOC 2, GDPR

планируется

Что можно получить бесплатно, а что за деньги?

Чаще всего, за деньги вы получаете доступ к более мощным языковым моделям, снятие ограничений по количеству запросов или улучшенный UX. Tabnine в платной подписке убирает ограничение на использование frontier-моделей (самые продвинутые доступные модели, например, GPT-4o), Codeium в варианте Pro даёт кредиты для использования с frontier-моделями и более продвинутую версию алгоритма сбора контекста. GigaCode предлагает покупку токенов для своих моделей напрямую. Qodo же предоставляет все функции для генерации тестов в бесплатной версии без ограничений, в том числе пользование frontier-моделями, добавляя в платную версию автодопополнение кода и несколько других, не относящихся к тестам функций. Explyt Test позволяет приобрести токены, чтобы использовать их для генерации. При обычном сценарии использования, программист в месяц в среднем тратит 3000 токенов.

Лимиты Diffblue отличаются от всех остальных провайдеров тем, что он предоставляет ограниченное число генераций – нажатий на кнопку «создать тест». 

Плагин

Работает в РФ

Бесплатно

За деньги

Codeium

нет

бесплатно только модели от Codeium

15$

GigaCode

да

10^6 бесплатных токенов

в зависимости от модели

Tabnine

нет

Tabnine модели: без ограничений, frontier-модели: 2-4 запроса в день

9$ (90 дней бесплатно)

Qodo

нет

без ограничений

19$ (14 дней бесплатно)

TestSpark

из исходников

Diffblue Cover

нет

25 генераций/месяц

30$: 100 генераций/месяц

Explyt Test

да

одноразово: 1000 токенов

1 руб/1 токен

В заключение

Существуют и другие подходы к генерации тестов. Для критически важного кода можно рассматривать инструменты, основанные на символьном исполнении, например, UTBot Java. Символьное исполнение позволяет эффективно перебирать состояния, в которые может попасть программа, а потому хорошо покрывает программу тестами.

В качестве менее фундаментального подхода можно выбрать решения, основанные на автоматическом анализе кода, например Squaretest, Jtest. За счет того, что гарантии корректности этих инструментов более слабые, код генерируется быстрее.

Мы готовим материал про альтернативные подходы к генерации тестов. О чем еще вам бы хотелось узнать и что интересно обсудить? Пробовали ли вы уже инструменты для автоматической генерации тестов, с LLM и без? Делитесь своим опытом и мнениями в комментариях. Спасибо, что дочитали до конца 🙂


ссылка на оригинал статьи https://habr.com/ru/articles/869198/