Плагин Tomcat7 Maven и JaCoCo
Есть ли способ получить покрытие кода с помощью JaCoCo с tomcat7-maven-plugin встроенный экземпляр?
Плагин jacoco-maven сконфигурирован в моей WAR POM для тестирования моих модульных тестов, но я не уверен, как подключить jacoco-агент к встроенному экземпляру Tomcat для тестирования моих интеграционных тестов, которые выполняются против Tomcat. Учитывая, что экземпляр Tomcat встроен, я не уверен, возможен ли этот подход. Есть ли другой способ сделать это? Возможно, я могу перейти от использования модуля Tomcat Maven Plugin к использованию Cargo, чтобы получить покрытие, но я предпочел бы придерживаться плагина Tomcat, если это возможно.
Вот несколько соответствующих фрагментов из моего POM:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.2.201302030002</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<systemProperties>
<!-- as expected, this system property doesn't work since Tomcat is embedded, but this is the type of config I'm looking for -->
<JAVA_OPTS>-javaagent:${project.build.directory}/${jacoco.jar}=destfile=${project.build.directory}/jacoco.exec,append=true</JAVA_OPTS>
</systemProperties>
</configuration>
<executions>
<execution>
<id>tomcat-startup</id>
<goals>
<goal>run-war-only</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<fork>true</fork>
</configuration>
</execution>
<execution>
<id>tomcat-shutdown</id>
<goals>
<goal>shutdown</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
</plugin>
Версии: Maven 3.0.4, Tomcat Maven Plugin 2.1, Jacoco 0.6.2.201302030002, Java 7
Ответы
Ответ 1
Я знаю, что это было некоторое время, так как вопрос был опубликован, но я не чувствую, что ответ действительно адресовал корень проблемы. Покрытие кода может работать с отказоустойчивым или надежным при выполнении тестов внутри этих плагинов. Однако, если вы просто хотите контролировать tomcat с jacoco, чтобы получить отчет о покрытии, текущая информация не предусматривает этого. Я обнаружил, что Tomcat7-maven-plugin не позволяет вам вводить javaagent для jacoco, просто предоставляя JAVA_OPTS. Перейдя на груз, я смог сделать это так.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<dataFile>${sonar.jacoco.reportPath}</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
<classDumpDir>${project.reporting.outputDirectory}/jacoco-it/classes</classDumpDir>
<skip>${skipITs}</skip>
</configuration>
<executions>
<execution>
<id>jacoco-agent</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<propertyName>jacoco.agent.itArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-report</id>
<phase>post-integration-test</phase>
<goals>
<goal>dump</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.11</version>
<configuration>
<skip>${skipITs}</skip>
<container>
<containerId>tomcat7x</containerId>
<zipUrlInstaller>
<url>http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.16/bin/apache-tomcat-7.0.16.zip
</url>
<downloadDir>${project.build.directory}/downloads</downloadDir>
<extractDir>${project.build.directory}/extracts</extractDir>
</zipUrlInstaller>
<dependencies>
<dependency>
<groupId>ojdbc</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
</dependencies>
</container>
<configuration>
<home>${project.build.directory}/catalina-base</home>
<properties>
<cargo.jvmargs>${jacoco.agent.itArgLine},output=tcpserver,port=6300 -Drunmode=TEST</cargo.jvmargs>
<cargo.servlet.port>9090</cargo.servlet.port>
</properties>
<configfiles>
<configfile>
<file>${basedir}/src/test/conf/context.xml</file>
<todir>conf/Catalina/localhost/</todir>
<tofile>context.xml.default</tofile>
</configfile>
</configfiles>
</configuration>
</configuration>
<executions>
<execution>
<id>start-tomcat</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-tomcat</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
важными частями являются:
-
<plugin><groupId>org.jacoco</groupId> ...<propertyName>jacoco.agent.itArgLine</propertyName>
-
<cargo.jvmargs>${jacoco.agent.itArgLine},output=tcpserver,port=6300 </cargo.jvmargs>
Когда цель отчета запускается в jacoco-плагине, он создаст каталог в ${projectbase}/target/site/jacoco-it/index.html с вашим докладом о покрытии. Я использую это с плагином soapui-maven, но он также может использоваться с selenium-maven-plugin.
Ответ 2
Вам не нужно передавать JAVA_OPTS в tomcat embedded, если вы используете maven-failafe-plugin (или maven-surefire-plugin) для запуска вашего теста интеграции. Это связано с тем, что tomcat встроен в один и тот же процесс maven-failafe-plugin.
Итак, когда jacoco-maven-plugin выполняет prepare-agent, он устанавливает argLine, что maven-failafe-plugin также использует.
Я создал проект для проверки этого, ниже части pom:
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.2.201302030002</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<includes>
<include>my.project.package.only.*</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>tomcat-startup</id>
<goals>
<goal>run-war-only</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<fork>true</fork>
</configuration>
</execution>
<execution>
<id>tomcat-shutdown</id>
<goals>
<goal>shutdown</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
<logOutput>true</logOutput>
<multiWindow>true</multiWindow>
</configuration>
</execution>
<execution>
<id>stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-server</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Ответ 3
вы можете попытаться взглянуть на обходной путь на этом посту: http://dougonjava.blogspot.co.il/2013/07/integration-testing-using-maven-tomcat.html
Ответ 4
Я решил проблемы при настройке агента JaCoCo со встроенным Tomcat, отключив классы классов, а затем просто разместив агент JaCoCo на пути Tomcat (зависимость плагина) и добавив файл jacoco-agent.properties.
Я установил рабочую конфигурацию в свой блог:
http://burkond.blogspot.de/2014/05/selenium-in-sonar-code-coverage-metrics.html
Ответ 5
У меня была такая же проблема, и единственным решением, которое я нашел, было установить ранее MAVEN_OPTS
в сборку Maven (например, в командной строке или в конфигурации задания Jenkins):
export MAVEN_OPTS=-javaagent:~/.m2/repository/org/jacoco/org.jacoco.agent/0.7.4.201502262128/org.jacoco.agent-0.7.4.201502262128-runtime.jar=destfile=./target/jacoco.exec,append=true
Это добавит агент jacoco во встроенный экземпляр tomcat, который сообщит результаты покрытия в заданный destfile
.
Во-первых, важно, чтобы путь к JAR-интерфейсу jacoco был правильным. Вы можете вручную загрузить и обратиться к нему или использовать другую команду Maven для ее загрузки в локальный репозиторий .m2:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get -Dartifact=org.jacoco:org.jacoco.agent:0.7.4.201502262128:jar:runtime
Во-вторых, убедитесь, что путь к файлу jacoco.exec
верен. В моем случае у меня уже есть файл jacoco.exec в целевой папке, содержащий результаты unit test. append=true
позволяет объединить тесты блока и интеграции.
Ответ 6
Мне удалось это сделать, и это связано с некоторыми издевательствами с фиктивными вещами:
- сервер/контейнер должен находиться на отдельном jvm, который может принимать аргументы (jacoco-agent). Груз с использованием встроенных контейнеров, похоже, не работал, и было больно отлаживать...
- jvm с jacoco - он должен остановиться перед анализом jacoco (duh!), но регистрация контейнера-стопа и jacoco-report на пост-интеграционном тесте не гарантирует этого... (опция tcpdump и т.д. в предыдущем ответ имел эту проблему)
- определение случайных портов для сервера/контейнера упрощает интеграцию с непрерывной интеграцией
- phantomjs является дополнительным;)
- jacoco следует использовать как интеграцию-подготовка-интеграцию и интеграцию отчетов для интеграции-теста (на самом деле не имеет значения)
Должен выполняться как 'mvn clean verify'
Pom:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<executions>
<!-- unit test coverage -->
<execution>
<id>jacoco-pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<propertyName>jacoco.ut.argLine</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-post-unit-test</id>
<phase>test</phase>
<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>
<!-- integration test coverage -->
<execution>
<id>jacoco-pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
<propertyName>jacoco.it.argLine</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report-integration</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.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.6</version>
</plugin>
<!-- Installs PhantomJS so it doesn't have to be pre-installed -->
<plugin>
<groupId>com.github.klieber</groupId>
<artifactId>phantomjs-maven-plugin</artifactId>
<version>0.4</version>
<executions>
<execution>
<!-- should be post-integration-test ? -->
<phase>test</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
<configuration>
<version>1.9.7</version>
</configuration>
</plugin>
<!-- Get two free ports for our test server to use -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<portNames>
<portName>jetty.port</portName>
<portName>jetty.port.stop</portName>
</portNames>
</configuration>
<executions>
<execution>
<id>reserve-port</id>
<phase>test</phase>
<goals>
<goal>reserve-network-port</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Run tests (UT) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<argLine>${jacoco.ut.argLine}</argLine>
<skipTests>${skip.unit.tests}</skipTests>
<testFailureIgnore>true</testFailureIgnore>
<excludes>
<!-- no UT execution, to test only IT
<exclude>**/<remove this>*Test.java</exclude> -->
</excludes>
</configuration>
</plugin>
<!-- Use failsafe to run our integration tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<!-- pass these values to the test classes -->
<phantomjs.binary>${phantomjs.binary}</phantomjs.binary>
<jetty.port>${jetty.port}</jetty.port>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.16</version>
<configuration>
<skip>${skipITs}</skip>
<container>
<containerId>tomcat8x</containerId>
<zipUrlInstaller>
<!-- did not work with 'https'. Certificate problem? -->
<url>http://archive.apache.org/dist/tomcat/tomcat-8/v8.0.26/bin/apache-tomcat-8.0.26.zip</url>
<downloadDir>${project.build.directory}/downloads</downloadDir>
<extractDir>${project.build.directory}/extracts</extractDir>
</zipUrlInstaller>
</container>
<configuration>
<home>${project.build.directory}/catalina-base</home>
<properties>
<cargo.jvmargs>${jacoco.it.argLine}</cargo.jvmargs>
<cargo.servlet.port>${jetty.port}</cargo.servlet.port>
<!-- <cargo.logging>high</cargo.logging> -->
</properties>
</configuration>
</configuration>
<executions>
<execution>
<id>cargo-start-tomcat</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>cargo-stop-tomcat</id>
<phase>integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>