Jacoco Integration test report is not correct - java

I have a restful api and the workflow of integration test cases is that we build the project -> Then start a tomcat using maven on a predefined port -> Deploy the built war on that tomcat instance and then maven runs the integration test cases with respect to that war. Build is succeeded only if the unit as well as integration test cases pass. I want to generate code coverage report for integration as well unit test cases. Though Jacoco is correctly generating report for unit test cases but it is not generating the correct report for integration test cases . As in all the folders are shown with zero percent coverage.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<executions>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${basedir}/target/jacoco-unit.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${basedir}/target/jacoco-unit.exec</dataFile>
<append>true</append>
</configuration>
</execution>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${basedir}/target/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<includes>
</includes>
<dataFile>${basedir}/target/jacoco-it.exec</dataFile>
<outputDirectory>${basedir}/target/site/jacoco-it</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
On failsafe plugin :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
<argLine>${failsafeArgLine}</argLine>
<skipTests>false</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>

Related

Not generate jacoco-ut.exec coverage report

Java 1.8. Maven 3.8. I want to generate coverage report of junit tests. So I use this in my pom.xml
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<executions>
<execution>
<id>prepare-ut-agent</id>
<phase>process-test-classes</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-ut.exec</destFile>
<propertyName>jacoco.agent.ut.arg</propertyName>
<append>true</append>
</configuration>
</execution>
<execution>
<id>prepare-it-agent</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-it.exec</destFile>
<propertyName>jacoco.agent.it.arg</propertyName>
<append>true</append>
</configuration>
</execution>
</executions>
</plugin>
Open terminal and run test like this:
mvn test -Dtest=com.my_company.myproject.ComponentServiceTest
Tests success finish. But coverage report to generate. File jacoco-it.exec is not exist in target folder
The pom.xml is missing the report goal as mentioned in the comment by #rajani-b.
Here is the configuration for the report goal.
<execution>
<id>report</id>
<goals>
<!--
Generate coverage reports in xml,csv,html formats
in folder ${project.build.directory}/site/jacoco
-->
<goal>report</goal>
</goals>
</execution>
Below is the complete <plugin> section for jacoco-maven-plugin for reference.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<executions>
<execution>
<id>prepare-ut-agent</id>
<phase>process-test-classes</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>jacoco.agent.ut.arg</propertyName>
<append>true</append>
</configuration>
</execution>
<execution>
<id>prepare-it-agent</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>jacoco.agent.it.arg</propertyName>
<append>true</append>
</configuration>
</execution>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<!--
Generate coverage reports in xml,csv,html formats
in folder ${project.build.directory}/site/jacoco
-->
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>

code coverage for component test not showing in multi-module project

I am using jacoco-maven-plugin to generate coverage report and using sonar-maven-plugin plugin to upload the report to SonarQube.
I am having below multi-module structure. BitBucket Project
mmproject
|
|---department-service
|
|---employee-service
|
|---component-test(This is for both the above services, code coverage for Controller)
I am using report-aggregate goal in pom.xml of component-test to merge the coverage report of employee-service, department-service and component-test module.
From component-test module.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<configuration>
<excludes>
<exclude>com/jigarnaik/mmproject/*/model/*/**</exclude>
<exclude>com/jigarnaik/mmproject/*/config/*/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>report-aggregate</id>
<goals>
<goal>report-aggregate</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
And below is the content of parent pom.
<properties>
<java.version>11</java.version>
<swagger.version>2.9.2</swagger.version>
<sonar.language>java</sonar.language>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/component-test/target/site/jacoco-aggregate/jacoco.xml
</sonar.coverage.jacoco.xmlReportPaths>
<sonar.java.binaries>${project.basedir}/target/classes</sonar.java.binaries>
<sonar.java.test.binaries>${project.basedir}/target/test-classes</sonar.java.test.binaries>
<sonar.exclusions>**/Application.java,**/model/*</sonar.exclusions>
</properties>
...
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<configuration>
<excludes>
<exclude>com/jigarnaik/mmproject/*/model/*/**</exclude>
<exclude>com/jigarnaik/mmproject/*/config/*/**</exclude>
<exclude>com/jigarnaik/mmproject/**/Application.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Jacoco coverage report which is more then 80% however when I see it on SonarQube the coverage is less then 50%. It's basically not showing coverage for any of the controller which is in my component-test module.
Am I missing something over here?

Jacoco coverage of unit and integration tests combined with coverageratio

In my project I use Jacoco plugin to show coverage report of unit tests,as well as integration tests,and one report which shows combined code coverage.Now I want to set coverageratio for that combined coverage,but my build is now failing because Jacoco only look for unit code coverage,not combined,which is smaller,of course, than specified report of combined.
Am I missing something in pom.xml?
Here is my configuration in pom.xml regarding to coverageratio:
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
EDIT: Maybe more nice way is to achieve is use the same file, but let it append another test, which works for us - unit and it tests.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.1</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<skip>${maven.surefire.skipTests}</skip>
<propertyName>maven.surefire.argLine</propertyName>
<!-- using the same dest file for both UT and IT -->
<destFile>${sonar.jacoco.reportPath}</destFile>
</configuration>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<skip>${maven.failsafe.skipTests}</skip>
<propertyName>maven.failsafe.argLine</propertyName>
<!-- append to the UT dest file -->
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${maven.surefire.skipTests}</skipTests>
<failIfNoTests>${maven.surefire.failIfNoTests}</failIfNoTests>
<!-- allow argLine to be modified by other plugins, e.g. jacoco -->
<argLine>#{maven.surefire.argLine}</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipTests>${maven.failsafe.skipTests}</skipTests>
<failIfNoTests>${maven.failsafe.failIfNoTests}</failIfNoTests>
<!-- allow argLine to be modified by other plugins, e.g. jacoco -->
<argLine>#{maven.failsafe.argLine}</argLine>
</configuration>
</plugin>
Original text: I got inspired another post as well in this blog resulting in following code, where is visible, that is measured coverage of unit tests, integration tests, then result is merged and only for whole bundle (not individual classes) it fails, if coverage is less than 70%.
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</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>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
<propertyName>testArgLine</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>
<execution>
<id>post-unit-test</id>
<phase>prepare-package</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>
<execution>
<id>merge-results</id>
<phase>verify</phase>
<goals>
<goal>merge</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<directory>${project.build.directory}/coverage-reports</directory>
<includes>
<include>*.exec</include>
</includes>
</fileSet>
</fileSets>
<destFile>${project.build.directory}/coverage-reports/aggregate.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-merge-report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/aggregate.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-aggregate</outputDirectory>
</configuration>
</execution>
<execution>
<id>check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/aggregate.exec</dataFile>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.70</minimum>
</limit>
<limit>
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.70</minimum>
</limit>
</limits>
<excludes>
<exclude>com.xyz.ClassToExclude</exclude>
</excludes>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
<argLine>${surefireArgLine}</argLine>
<skipTests>${skip.unit.tests}</skipTests>
<includes>
<include>**/*UT.java</include>
<include>**/*MT.java</include>
<include>**/*Test.java</include>
</includes>
<skipTests>${skipUTMTs}</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.21.0</version>
<configuration>
<skipTests>${skipTests}</skipTests>
<skipITs>${skipITs}</skipITs>
<argLine>${testArgLine}</argLine>
<excludes>
<exclude>**/*UT*.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The accepted answer didn't work for me, having Jacoco write two files, one for the unit tests and other for integration tests, then merging these two files and generating the report from the single merged file as follows did:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.4</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-unit.exec</destFile>
</configuration>
</execution>
<execution>
<id>prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-integration.exec</destFile>
<append>true</append>
</configuration>
</execution>
<execution>
<id>report</id>
<phase>post-integration-test</phase>
<goals>
<goal>merge</goal>
<goal>report</goal>
</goals>
<configuration>
<!-- merge config -->
<destFile>${project.build.directory}/jacoco.exec</destFile>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>*.exec</include>
</includes>
</fileSet>
</fileSets>
<!-- report config -->
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
</configuration>
</execution>
</executions>
</plugin>

Tomcat7 Maven Plugin and JaCoCo

Is there any way to get code coverage using JaCoCo with the tomcat7-maven-plugin embedded instance?
The jacoco-maven-plugin is configured in my WAR's POM to instrument my unit tests, but I'm not sure how to attach the jacoco agent to the embedded Tomcat instance to instrument my integration tests that run against Tomcat. Given that the Tomcat instance is embedded, I'm not sure if this approach is possible. Is there any other way to accomplish this? I can probably switch from using the Tomcat Maven Plugin to using Cargo to get coverage, but I'd prefer to stick with the Tomcat plugin if possible.
Here are a few relevant snippets from my 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>
Versions: Maven 3.0.4, Tomcat Maven Plugin 2.1, Jacoco 0.6.2.201302030002, Java 7
I know its been awhile since the question was posted but I don't feel the answer really addressed the root of the problem. Code coverage may work with failsafe or surefire if you are running tests within those plugins. However, if you just want to monitor tomcat with jacoco to get a coverage report current information doesn't provide that. I found that the tomcat7-maven-plugin doesn't allow you to inject the -javaagent for jacoco by simply providing JAVA_OPTS. Switching to cargo I was able to do that like so.
<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>
the important parts are:
<plugin><groupId>org.jacoco</groupId> ...<propertyName>jacoco.agent.itArgLine</propertyName>
<cargo.jvmargs>${jacoco.agent.itArgLine},output=tcpserver,port=6300 </cargo.jvmargs>
When report target is run on the jacoco plugin it will create a directory in ${projectbase}/target/site/jacoco-it/index.html with your coverage report. I use this with the soapui-maven-plugin but it could be used with selenium-maven-plugin also.
You don't need pass JAVA_OPTS to tomcat embedded if you use maven-failsafe-plugin (or maven-surefire-plugin) to run yours integration test. It is because tomcat embedded run in the same process of maven-failsafe-plugin.
So when jacoco-maven-plugin execute prepare-agent it sets argLine that maven-failsafe-plugin uses too.
I created a project to test this, below part of 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>
you can try to take a look at a workaround at this post: http://dougonjava.blogspot.co.il/2013/07/integration-testing-using-maven-tomcat.html
I resolved problems when setting up JaCoCo agent with embedded Tomcat by instrumenting classes offline and then just placing JaCoCo agent on Tomcat classpath (plugin dependency) and adding file jacoco-agent.properties.
I put the working configuration on my blog:
http://burkond.blogspot.de/2014/05/selenium-in-sonar-code-coverage-metrics.html
I had the exact same problem and the only solution I found was to set the MAVEN_OPTS previously to the Maven build (for example on the command line or in the configuration of a Jenkins job):
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
This will attach the jacoco agent to the embedded tomcat instance, which will report back the coverage results into the given destfile.
First, it is important that the path to the jacoco runtime JAR is correct. You can manually download and refer to it or use another Maven command to download it into your local .m2 repository:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get -Dartifact=org.jacoco:org.jacoco.agent:0.7.4.201502262128:jar:runtime
Second, make sure that the path to the jacoco.exec file is correct. In my case, I already have an existing jacoco.exec file in the target folder, which contains unit test results. The append=true makes sure that unit and integration tests are combined.
I managed to do it and it involves some tinkering with finicky stuff:
server/container needs to be on a separate jvm that can receive arguments (jacoco-agent). Cargo using embedded containers did not seem to work and was a pain to debug...
jvm with jacoco-it needs to stop before the jacoco analysis (duh!) but registering container-stop and jacoco-report on post-integration-test does not guarantee this... (the tcpdump, etc option in a previous answer had this problem)
defining random ports for the server/container makes this easy to integrate with continuous integration
phantomjs is an extra ;)
jacoco should be used as prepare-agent-integration and report-integration for integration-test (does not really make a difference)
Should be run as '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>

Integration tests wouldn't start (Failsafe, Maven)

I'm trying to use Maven Failsafe Plugin to run my integration tests with this configuration:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.7</version>
<configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>3600000</maxIdleTime>
</connector>
</connectors>
<contextPath>/</contextPath>
<scanIntervalSeconds>3</scanIntervalSeconds>
<scanTargetPatterns>
<scanTargetPattern>
<directory>src/main/webapp/WEB-INF</directory>
<excludes>
<exclude>**/*.jsp</exclude>
<exclude>**/*.html</exclude>
</excludes>
<includes>
<include>**/*.page</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</scanTargetPattern>
</scanTargetPatterns>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-war</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
Everything is fine until Jetty is started in pre-integration-test phase. Then nothing happens, as if it was waiting for something. The last line says:
[INFO] Started Jetty Server
How can I make the tests to start right afterwards? I run maven using mvn verify.
Change of jetty maven plugin version from 6.1.7 to 6.1.26 solved everything.
For people still looking for a solution, I had that same problem and I solved it by replacing
<goals>
<goal>run-war</goal>
</goals>
by
<goals>
<goal>start</goal>
</goals>
It works because run* are blocking the execution, while start is non-blocking.

Categories