Тестовые фикстуры: управление зависимостями в Gradle

от автора

Gradle позволяет разделять приложение на подпроекты. Иногда при определении зависимостей тестовые фикстуры не вписываются ни в структуру production кода, ни в структуру тестового кода. В этой статье мы расскажем о малоизвестной возможности Gradle, которая позволяет тестовым фикстурам занять естественное место в системе зависимостей.

Тестовые фикстуры — это вспомогательные классы и ресурсы, на основе которых строятся тесты. Например:

  • Инициализация класса модели тестовыми данными

  • Вспомогательные методы для обработки и проверки JSON

  • Широко используемые конструкции с мок-объектами

Тестовые фикстуры часто создаются путем выделения кода, который используется в нескольких тестовых классах. Ситуация становится особенно интересной, если такой код необходимо использовать в нескольких Gradle подпроектах.

Проблема: ни тестовый, ни production код

В этом примере у нас есть приложение с тремя Gradle sub-project-ами: app, domain и exporters:

Для тестов в проекте domain требуются конкретные тестовые данные. Они создаются в отдельном классе TestDataFactory. Эта фабрика также могла бы служить полезной основой для тестирования JSON-экспортера в проекте exporters. К сожалению, напрямую определить такую зависимость нельзя. Это ограничение является осознанным архитектурным решением Gradle, поскольку тесты обычно только выполняются и не предоставляют артефакты для других проектов.

Решение: плагин java-test-fixtures

Начиная с Gradle 5.6 тестовые фикстуры поддерживаются на уровне платформы:

Для этого соответствующий плагин Gradle подключается к подпроекту, который предоставляет тестовые фикстуры (пример domain/build.gradle):

plugins {    id 'java-library'    id 'java-test-fixtures'}dependencies {    // ...    testFixturesImplementation 'com.google.guava:guava:31.1-jre'}

После этого Gradle автоматически создает и настраивает новый SourceSet под названеим testFixtures в дополнение к main и test. Стандартная структура каталогов выглядит следующим образом:

︙├── domain│   ├── build.gradle│   └── src│       ├── main│       │   └── java│       │       └── de/cronn│       │              └── CustomerEntity.java│       ├── test│       │   └── java│       │       └── de/cronn│       │              └── ModelTest.java│       └── testFixtures│           └── java│               └── de/cronn│                      └── TestDataFactory.java└── exporters    ├── build.gradle    ︙

Зависимости тестовых фикстур можно указывать с помощью конфигураций testFixturesImplementation и testFixturesApi. Они работают аналогично конфигурациям implementation и api плагина java-library.

Подключение тестовых фикстур в качестве зависимости

На последнем этапе объявляется зависимость в build.gradle проекта exporters:

dependencies {    // ...    testImplementation testFixtures(project(':domain'))}

При такой конфигурации класс ExportTest из проекта exporters получает доступ к TestDataFactory из проекта domain.

Отдельные проекты

Совместное использование тестовых фикстур возможно не только между подпроектами Gradle, но и между отдельными проектами.

В таких случаях зависимости устанавливаются через опубликованные артефакты. При использовании плагина java-test-fixtures дополнительная настройка не требуется. По умолчанию автоматически создается и публикуется еще один артефакт:

mygroup├── myproject│   └── 1.0│       ├── myproject-1.0-plain.jar│       ├── myproject-1.0-sources.jar│       ├── myproject-1.0-test-fixtures.jar│       ├── myproject-1.0.module│       └── myproject-1.0.pom

При использовании собственного плагина Gradle maven-publish дополнительная метаинформация сохраняется в файле *.module. 

Благодаря этому во втором проекте зависимости можно объявить в ожидаемом формате:

dependencies {    // ...    testImplementation testFixtures("mygroup.myproject:1.0")}

Поддержка в IDE

Поскольку плагин Gradle основан на уже существующих механизмах SourceSet-ов, поддержка со стороны IDE реализована хорошо. При поиске текста и символов IDE обычно позволяют применять фильтрацию. Результаты поиска можно ограничить тестовым или производственным кодом. При этом тестовые фикстуры классифицируются по-разному:

  • В Eclipse тестовые фикстуры (корректно) относятся к тестовому коду.

  • В IntelliJ тестовые фикстуры считаются производственным кодом. Чтобы изменить их классификацию при фильтрации, можно настроить собственные области видимости.

Ссылки

Документация Gradle по тестовым фикстурам

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.

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