Перейти к основному содержимому

Генерация тестов по исполнению (Test Generation from Execution)

0. Прежде чем начать

Что такое Test Generation from Execution?

Функция генерации тестов по исполнению (Test Generation from Execution) позволяет разработчикам фиксировать запуски приложения и автоматически создавать юнит-тесты, точно повторяющие поведение системы. Сложные сценарии больше не нужно воссоздавать вручную — достаточно записать и воспроизвести.

Например, вы можете запустить приложение Spring Boot (локально или удалённо), поработать с его веб-интерфейсом (отправить форму или нажать кнопку) и затем сгенерировать модульные тесты, которые воспроизводят те же вызовы сервисов, что были зафиксированы во время вашей сессии.

Во время исполнения фиксируются:

  • входные и выходные данные, исключения;
  • иерархия вызовов и состояние объектов;
  • моки внешних зависимостей.

Записанная трасса автоматически преобразуется в автономный, готовый к запуску юнит-тест.

Функция разработана прежде всего для проектов на Spring, однако её можно использовать с любым Java- или Kotlin-кодом.

Как это работает?

Функция работает как отладчик — наблюдает за исполнением вашей программы:

  1. Трассировка исполнения
    Вы запускаете приложение, тест или метод через стандартную конфигурацию запуска, а мы подключаемся к запущенному процессу через Java Debug Interface (JDI) и отслеживаем вызовы методов, аргументы, возвращаемые значения и исключения.

  2. Трасса исполнения
    Пока программа работает, мы фиксируем поведение тестируемого метода — входные данные, поток управления, внутреннее состояние.

    • Сначала исследуется объект this — его поля и контекст создания.
    • Затем анализируются все аргументы метода — примитивы, коллекции, пользовательские объекты.
    • Наконец, изучаем трассируем метода: вложенные вызовы, исключения и возвращаемые результаты.
  3. Восстановление объектов по эвристикам
    Чтобы сделать тест реалистичным и читаемым, применяются эвристики, похожие на те, что использует разработчик:

    • Простые объекты (например, POJO или data class) воссоздаются через конструкторы или билдеры.
    • Сложные/внешние объекты (например, сервисы, сокеты, БД) мокируются с помощью выбранного фреймворка.
    • Если объект сериализуем, он сериализуется в JSON и восстанавливается из него — для читаемости и воспроизводимости.
  4. Генерация теста
    После исполнения по собранным данным создаётся юнит-тест, который воспроизводит оригинальное поведение.
    В тесте есть создание необходимых объектов, моки, вызов метода и проверки (assert).

  5. Искусственный интеллект для доработки
    Код рефакторится и дорабатывается с помощью современных LLM.
    В результате получается читаемый, идиоматичный тест, соответствующий стилю вашего проекта.

✔ Вы получаете готовый юнит-тест, основанный на реальном исполнении — написанный так, как это сделал бы разработчик.

Какие языки поддерживаются?

На данный момент поддерживаются:

  • Java
  • Kotlin

1. Как начать?

Нажмите на иконку Explyt (gutter icon) рядом с методом, для которого нужно сгенерировать тест или кликните правой кнопкой в теле метода. Выберите "Generate Tests From Execution" в контекстном меню.

gutter


2. Окно настроек

После запуска откроется окно конфигурации:

main_window

Общие настройки

  • Output to Выбор способа сохранения тестов.

    • New test class – Создать новый класс с тестами. Файл будет сохранён в директории, указанной в разделе Location And Frameworks.

    • Existing test class – Добавить тесты в уже существующий тестовый класс. Если для класса ранее генерировались тесты при помощи функции Generate Tests From Execution, этот вариант выберется автоматически.

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

  • Use example test class (доступно при Output to: New test class)
    Использовать выбранный тестовый класс как шаблон (импорты, структура, стиль и т. д.)

    • Example tests – выбранный класс (например, SchemaRegistryControllerServiceTest). Нажмите иконку с карандашом для изменения.
  • Class to expand (доступно при Output to: Existing test class)
    Класс, в который будут добавлены тесты. Нажмите иконку с карандашом для изменения.

  • Generate tests for successful executions
    Создавать тесты для успешно завершённых вызовов.

  • Generate tests for exceptional executions
    Создавать тесты для вызовов, завершившихся исключением.

  • Generate tests only for executions that hit the breakpoint
    Генерация тестов будет производиться только для тех трасс исполнения, которые прошли через заданный breakpoint. Можно использовать стандартные breakpoint'ы IntelliJ IDEA, включая conditional breakpoints.


Location And Frameworks

  • Test source root (доступно при Output to: New test class)
    Каталог для сохранения класса тестов, обычно src/test/java.

  • Test package (доступно при Output to: New test class)
    Название пакета нового тестового класса.

  • Test framework Все фреймворки, найденные в проекте. Выберите, какой использовать:

    • JUnit 5 — рекомендуется для современных Java/Kotlin-проектов.
    • JUnit 4 — для старых или смешанных кодовых баз.
  • Mock framework Доступные фреймворки мокирования:

    • Mockito — выбор по умолчанию для Java.
    • MockK — рекомендуется для Kotlin.
    • kotlin-mockito — поддерживается как запасной вариант.

Execution Source

Выбор способа запуска программы.

▶ Run Configuration

Используйте одну из существующих конфигураций запуска (Run Configuration) в IntelliJ IDEA.

  • В дереве отображаются все ранее запущенные конфигурации (JUnit-тесты, методы main, Maven/Gradle конфигурации).
  • Разверните нужную группу и выберите конфигурацию.

✔ Рекомендуемый способ: быстро и просто.

▶ Local Process

Подключитесь к локально работающей JVM (например, микросервису, фоновой задаче или CLI-приложению).

Требования:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:PORT

process_start

⚠ Для Java 8 уберите «*:», оставив только номер порта: address=5005.

  • Запущенные процессы с JDWP появятся в списке:

running_process

  • Выберите процесс и нажмите Generate Tests.

▶ Remote Process

Подключитесь к JVM на другом хосте (на другой машине, в контейнере или на staging-сервере).

Требования:

  • Удалённая JVM должна быть запущена с включённым JDWP:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:PORT
  • Вам нужно указать:
    • Host – IP или имя хоста целевой машины (например, 127.0.0.1 или staging.myapp.com)
    • Port – Порт, на котором JDWP слушает (например, 8000)

⚠ Убедитесь, что правила firewall или политики сети позволяют это подключение.


Кнопка Generate Tests

Нажмите эту кнопку, чтобы начать генерацию тестов.


3. Прогресс

После запуска программы Вы увидите окно прогресса:

captured_calls

  • Capturing calls to UsersTeamsControllerService.getTeamDetails() – показывает, какой метод трассируется.

⏳ Трассировка может занять больше времени, чем обычное исполнение, так как мы записываем все аргументы и возвращаемые значения.

  • Calls captured: N – счётчик зафиксированных вызовов.

  • Stop Listening And Generate Tests – Завершает трассировку и начинает генерацию тестов. Все зафиксированные вызовы будут преобразованы в тестовые методы.

Если целевой метод вызывается несколько раз, все вызовы будут зафиксированы.


4. Программа завершилась

После завершения генерации тесты сохраняются в указанную директорию или добавляются в существующий тестовый класс.

final_test

  • Тесты автоматически рефакторятся с помощью IntelliJ IDEA и LLM.
  • Форматирование, импорты, имена и структура подстраиваются под стиль вашего проекта.

⚠ Некоторые особые случаи — такие, как нативные ресурсы, глубокие моки или внешние зависимости — могут потребовать небольшой ручной доработки.

Вы по-прежнему управляете процессом — мы просто избавляем вас от рутины.