Привет, Хабр! Для большинства разработчиков тесты – это нелюбимая часть работы. Недавно мы убедились в этом, опросив больше 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.
☝️
