Jacoco и Jetty Maven плагин получает 0% покрытия
Я пытаюсь настроить Jacoco, чтобы получить покрытие для моих интеграционных тестов. Я запускаю свои интеграционные тесты против Jetty (используя плагин maven). Но даже если я передаю агент в аргументах варенья при запуске сервера Jetty, отчет jacoco показывает 0%. Вот мой pom.xml
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-forked</goal>
</goals>
<configuration>
<waitForChild>false</waitForChild>
<jvmArgs>-Denv=it -Djetty.port=8081 ${failsafeArgLine}</jvmArgs>
<webApp>
<contextPath>/myContext</contextPath>
</webApp>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<stopPort>8082</stopPort>
<stopKey>test</stopKey>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<argLine>${failsafeArgLine}</argLine>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Как вы можете видеть, я управляю причалом в режиме форка, и я передаю агента jacoco в параметрах, но ничего...
Есть ли что-то еще, что мне нужно добавить?
2 ответа
Есть много ответов от людей, которые прочитали справку и ответили, не имея ни малейшего представления о том, что действительно нужно, чтобы заставить ее работать.
Так мы пошли..
Обо всем по порядку. Maven запускает вещи, основываясь на фазах, с которыми они связаны, однако, если у вас есть две вещи, связанные с одной и той же фазой, Maven выполнит их в порядке их появления в файле POM, поэтому в этом случае порядок имеет значение.
Вот как выглядит мой POM-файл:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<argLine>${surefireArgLine}</argLine>
<skipTests>${skip.unit.tests}</skipTests>
<excludes>
<exclude>**/*TestSuite*</exclude>
<exclude>**/*ITest*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<configuration>
<skipTests>${skip.integration.tests}</skipTests>
<includes>
<include>**/*TestSuite*</include>
<include>**/*ITest*</include>
</includes>
<systemPropertyVariables>
... //Whatever you need to configure on your integration test, if any.
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<excludes>
<exclude>**/*Test*</exclude>
</excludes>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
<excludes>
<exclude>**/*Test*</exclude>
</excludes>
<propertyName>jacoco.agent.itArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.10.v20150310</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<httpConnector>
<port>${it.server.port}</port>
</httpConnector>
<contextXml>jetty_context.xml</contextXml>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-forked</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
<waitForChild>false</waitForChild>
<maxStartupLines>200</maxStartupLines>
<jvmArgs>${jacoco.agent.itArgLine} -Djetty.port=${it.server.port}</jvmArgs>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
Это фактическая рабочая конфигурация POM.xml. Теперь давайте перейдем к важным деталям:
- Плагин Jacoco должен продолжить плагин Jetty, иначе у вас не будет свойства с конфигурацией javaagent
- Вы должны запустить Jetty разветвленный, иначе Jetty не примет конфигурацию javaagent.
- Так как вы запускаете Jetty разветвленный, вы не можете использовать
<webApp>...</webApp>
определить контекстный путь. Для этого вам понадобится файл context.xml. Я использую один для Jetty и другой для Tomcat (производство). Смотрите содержание ниже. - Отчеты Jacoco о интеграционных тестах не могут быть привязаны к фазе после интеграционного тестирования, в противном случае вы будете сообщать о результатах до фактического их сбора. (Предполагая, что вы хотите, чтобы Jacoco сообщал, если вы не пропустите это). Таким образом, вы должны привязать его к следующему доступному этапу, который будет проверен.
- MaxStartupLines используется, чтобы сообщить Jetty, сколько строк инициализации он может игнорировать, прежде чем допустить, что произошла ошибка инициализации. Возможно, вам придется настроить это.
Context.xml (jetty_context.xml):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/myApp</Set>
<Set name="extraClasspath">comma-separated list of additional classpaths, such as resources</Set>
</Configure>
Если вы хотите также сообщить о своем покрытии кода в SonarQube:
<properties>
<sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco-ut.exec</sonar.jacoco.reportPath>
<sonar.jacoco.itReportPath>${project.build.directory}/coverage-reports/jacoco-it.exec</sonar.jacoco.itReportPath>
</properties>
Если все остальное правильно, вы сможете запустить:mvn clean install sonar:sonar
Я сам немного поработал с этим в последние пару дней и приведу рабочий пример:
https://github.com/daniellundmark/jetty-jacoco-example
Может быть, это может помочь вам.
При запуске вашего примера выше, я получил эту ошибку:
[INFO] Forked process starting
[INFO] Forked process startup errors
Я получил ваш пример работы (с некоторым записанным покрытием), переключившись на подготовку агентов, интеграцию отчетов и перемещение плагина перед подключаемым модулем в файле pom.
Было полезно запустить mvn -X pre-интеграционный тест, чтобы увидеть, что произошло. Но взгляните и на приведенный выше пример. Надеюсь, это поможет вам.
Вот плагины, которые я использовал в файле pom.xml при изменении вашего примера:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-forked</goal>
</goals>
<configuration>
<waitForChild>false</waitForChild>
<jvmArgs>${failsafeArgLine} -Denv=it -Djetty.port=8081</jvmArgs>
<webApp>
<contextPath>/myContext</contextPath>
</webApp>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<stopPort>8082</stopPort>
<stopKey>test</stopKey>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<argLine>${failsafeArgLine}</argLine>
</configuration>
</execution>
</executions>
</plugin>