Покрытие кода в сборке Maven - Пропуск выполнения JaCoCo из-за отсутствия каталога классов
Я могу получить покрытие кода, работающее нормально, если у меня есть один проект, но теперь у меня есть многомодульный проект.
Мое приложение построено в проекте api, и все мои интеграционные тесты выполняются в отдельном проекте, в котором используется артефакт, созданный как предыдущий модуль.
Сборка выполняется, но я не получаю отчет о покрытии кода, вместо этого я получаю информационное сообщение:
Пропуск выполнения JaCoCo из-за отсутствия каталога классов
Мой файл отчета о покрытии jacoco-it.exec создан, но похоже, что плагину jacoco требуются классы в проекте, в котором выполняются тесты.
Может кто-нибудь сказать мне, что мне нужно сделать, чтобы иметь возможность создать отчет о покрытии, когда классы находятся в другом модуле?
1 ответ
Мне удалось получить обходной путь через проб и ошибок.
Кажется, плагин jacoco счастлив создать exec-файл без классов, но он не создаст отчет без них, я не понимаю, как работает jacoco, поэтому, если кто-то знает, не могли бы вы объяснить это?
Я также не уверен, что то, что я сделал, является надежным, но, похоже, оно сообщает об охвате моих тестов на селен.
Мое (возможное) решение, которое я придумал сам, - это использовать плагин ресурсов maven, чтобы скопировать классы, которые были разобраны из файла war в моем каталоге target\cargo.., в каталог target \ classes:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>pre-integration-test</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<directory>${basedir}/target/cargo/configurations/tomcat7x/webapps/calculator-api/WEB-INF/classes</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*Config*.*</exclude>
<exclude>**/*Initialiser*.*</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Это, кажется, делает плагин jacoco счастливым, и я получаю покрытие кода, хотя кажется, что плагин теперь игнорирует мой список исключений.
Кто-нибудь знает, если это действительно решение, оно "кажется" работает, но я не могу найти где-нибудь в Интернете, где это рекомендуемый подход, и я также не уверен, почему опция exclude в настройке агента jacoco больше не работает.
Мне удалось обойти плагин jacoco, не исключая файлы, просто не копируя их с плагином ресурсов, но я до сих пор не понимаю, как именно работает jacoco.
Даже не смотря на jacoco:report-aggregate
предназначался для агрегированного отчета по зависимостям, в моем случае он не работал - я использую структуру проекта, например:
project
└─ module-api ⇦ API definition
└─ module-spec ⇦ module with black box tests through the API
└─ module-impl1 ⇦ implementation 1 of the API
└─ module-impl2 ⇦ another implementation of the API
└─ module-test1 ⇦ some dependencies + impl1, apply the tests from spec
└─ module-test2 ⇦ some dependencies + impl2, apply the tests from spec
В этом случае report-aggregate
сформировал пустой отчет. Проекты module-test1 и module-test2 имеют тип упаковки POM, который не подходит для запуска.report
на них тоже, поскольку для этого требуются классы в каталоге target / classes.
Мое решение
Я настроил плагин jacoco, чтобы выгрузить классы, которые он использует в каталоге target / classes проекта, добавив:<classDumpDir>${project.build.outputDirectory}</classDumpDir>
Это позволило регулярному report
цель работать. Полный код:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<destFile>${project.build.directory}/coverage-reports/code-coverage.exec</destFile>
<dataFile>${project.build.directory}/coverage-reports/code-coverage.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/code-coverage</outputDirectory>
<propertyName>jacocoArgLine</propertyName>
<classDumpDir>${project.build.outputDirectory}</classDumpDir>
</configuration>
<executions>
<execution>
<id>prepare-jacoco-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Обратите внимание, что инструментированные классы принадлежат ко всем зависимостям, поэтому потребуется некоторая фильтрация, чтобы сузить область действия отчета. См. https://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html
У меня аналогичная структура проекта - основной код находится в одном модуле, а тесты - в другом - и возникла аналогичная проблема с отчетами jacoco.
Мое решение 1:
Просто скопируйте /classes
папка для тестирования модуля maven-resources-plugin
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-classes-to-test-module</id>
<goals>
<goal>testResources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/../main-module/target/classes</directory>
</resource>
</resources>
<outputDirectory>
${project.build.outputDirectory}
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Но если ваш код содержит лямбды, анонимные классы и т. Д., То отчет о результатах может не охватывать некоторые классы, потому что это будут разные классы из-за разных prepare-agent
бежит.
Мое решение 2:
Использовать report-aggregate
Цель.
В родительском POM у меня есть такая конфигурация:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<configuration>
<append>true</append>
</configuration>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
И POM тестового модуля содержит следующие строки:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
Помните, что область зависимости важна для report-aggregate
цель (jacoco docs). Если ваш тестовый модуль имеет только зависимости в тестовой области, вы получите пустой отчет. Следовательно, вы должны установить область для компиляции, выполнения или предоставления тех артефактов, которые вы хотите видеть в отчете. Например:
<dependency>
<groupId>my.project</groupId>
<artifactId>main-module-classes</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
Вы можете использовать цель jacoco:report-aggregate
который как раз предназначен для создания отчетов о покрытии в отдельном тестовом модуле.
Вот пример:
project
└─ module ⇦ module with sources
└─ module-test ⇦ module with tests
Тогда все, что вам нужно сделать, это использовать эту цель в pom.xml файла "module-test":
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>jacoco-report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Также будьте осторожны с областями действия, которые вы используете в своих зависимостях, как указано в документации.