maven jacoco not generating code coverage for Integration tests - spring

I have a multi-module java spring boot project. Here is my project structure
- pom.xml (root)
- war (project)
--- pom.xml
--- src/.../SBMainApplication.java
- api (project)
--- pom.xml
--- src/../Controller1.java
--- test/unit/
--- test/integration
- service (project)
--- pom.xml
--- src/../Service1.java
--- test/unit/
- domain(project)
--- pom.xml
--- src/../Repository1.java
--- test/unit/
As you can see, there are 4 modules and finally when war module is built it pakages other modules as a Spring Boot jar.
I have enabled jacoco for code coverage and it works fine for all unit tests, which are there in each module. The integration tests however only exist in api module. My expectation is if I am running a SpringRunner integration on API and the flow is Controller1 -> Serivice1 -> Repository1 -> h2 database, the integration tests would cover all the classes in other modules too. But in the jacoco coverage only the controllers are being covered but the services and repositories are not covered. Here is my jacoco configuration in the root pom
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<excludes>
<exclude>com/../model/**/*</exclude>
<exclude>com/../common/model/**/*</exclude>
<exclude>com/../repository/entity/**/*</exclude>
<exclude>**/*Constants.java</exclude>
<exclude>**/*Configuration.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>jacoco-initialize-ut</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>jacoco-initialize-it</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<excludes>
<exclude>com/../model/**/*</exclude>
<exclude>com/../common/model/**/*</exclude>
<exclude>com/../repository/entity/**/*</exclude>
<exclude>**/*Constants.java</exclude>
<exclude>**/*Configuration.java</exclude>
</excludes>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0%</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
<execution>
<id>jacoco-report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<excludes>
<exclude>**/*IntTest.java</exclude>
</excludes>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<include>**/*IntTest.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
Is there a way where service and repositories are covered in jacoco by running the integration tests in another module?

Related

Jacoco report in JUnit report output directory

I have a simple Maven project configured to generate a JUnit report with the Surefire plugin, and a coverage report with Jacoco.
After running mvn test, I expect to find:
jacoco report files in reports/jacoco
surefire-report.html in reports/junit
However for some reason the Jacoco report files appear in both the reports/jacoco AND reports/junit folder:
Please help me to understand and correct.
pom.xml:
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${surefire.plugin.version}</version>
<configuration>
<outputDirectory>${basedir}/reports/junit</outputDirectory>
</configuration>
<executions>
<execution>
<id>during-tests</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.plugin.version}</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/reports/jacoco</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
...

jacoco including apache in report

i am first time trying jacoco for coverage :
but jacoco reports also include apache dependecies it it.
here is my pom.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
<excludes>
<exclude>*org/apache/*</exclude>
</excludes>
<outputDirectory>${project.reporting.outputDirectory}/jacoco</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
i tried
<exclude>**/lib/*</exclude>
also. nothing is removing this apache coverage from report.
below is project structure.
for my code below exclude worked
<exclude>**/axis-1.4.jar/**</exclude>

Jacoco analyzed bundle '...' with 0 classes when used with Cucumber

I am currently working on Jacoco code coverage for a Maven project with Cucumber integration tests.
My pom.xml file has jacoco and failsafe plugins as shown in the pictures, with reference from https://github.com/dimazelinskyi/jacoco-coverage-cucumber-unit-tests.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.basedir}/target/jacoco-reports/jacoco-test.exec</destFile>
<propertyName>failsafeJacocoAgent</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-site</id>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.basedir}/target/jacoco-reports/jacoco-test.exec</dataFile>
<outputDirectory>${project.basedir}/target/jacoco-reports/jacoco-test</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<argLine>${failsafeJacocoAgent}</argLine>
</configuration>
</execution>
<execution>
<id>junit-integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<testNGArtifactName>none:none</testNGArtifactName>
<argLine>${failsafeJacocoAgent}</argLine>
</configuration>
</execution>
<execution>
<id>testng-integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<argLine>${failsafeJacocoAgent}</argLine>
</configuration>
</execution>
</executions>
<configuration>
<includes>
<include>**/CukeRunnerTest.java</include>
</includes>
<systemPropertyVariables>
<isMavenTest>true</isMavenTest>
<client.uri>${wipdm.app.base.url}</client.uri>
<cucumber.options>${async.option}</cucumber.options>
</systemPropertyVariables>
<properties>
<async.option>--tags ~#longRunningTest</async.option>
</properties>
</configuration>
</plugin>
And the CukeRunnerTest.java file looks like this: CukeRunnerTest.java
When I build with maven i.e. mvn clean install, all tests successfully pass, however I get a message saying
[INFO] Loading execution data file C:\Users\...\IdeaProjects\...\target\jacoco-reports\jacoco-test.exec
[INFO] Analyzed bundle 'wipdata-war' with 0 classes
The build is successful and jacoco-it.exec file is generated, but no reports are generated.
Is this expected behaviour? As I thought that jacoco would check the Cucumber feature files inside "src/test/features/v3" (which is stated inside CukeRunnerTest.java) to see which code in the java files they covered in their integration tests.
Any advice or help is much appreciated.

How to make reserve-network-port work with maven spring project

I am trying to implement reserve-network-port with my maven spring project.
My POM
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>reserve-network-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<portNames>
<portName>tomcat.http.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
<configuration>
<systemProperyVariables>
<build.profile.url>${build.profile.url}</build.profile.url>
<test.server.port>${tomcat.http.port}</test.server.port>
</systemProperyVariables>
<skipTests>${skip.integration.tests}</skipTests>
</configuration>
</execution>
</executions>
</plugin>
${tomcat.http.port} is returning null for me.
I am also getting the prot no reserved when my maven build is started
[INFO] --- build-helper-maven-plugin:1.10:reserve-network-port (reserve-network-port) # account-service ---
[INFO] Reserved port 58140 for tomcat.http.port

Maven Jacoco Configuration - Exclude classes/packages from report not working

I have a maven multi-module project and I'm using jacoco-maven for code coverage reports. Some classes should not be reported, as they're Spring configuration and I'm not interested in them.
I have declared the maven-jacoco plugin as follow:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
<configuration>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
<exclude>some.package.*</exclude>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
<exclude>some/package/SomeClass.java</exclude>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
The problem is that when I execute mvn clean verify jacoco still reports classes that should have been excluded as my xml configuration points out. How can I configure it properly?
Your XML is slightly wrong, you need to add any class exclusions within an excludes parent field, so your above configuration should look like the following as per the Jacoco docs
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<configuration>
<excludes>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>jacoco-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
The values of the exclude fields should be class paths (not package names) of the compiled classes relative to the directory target/classes/ using the standard wildcard syntax
* Match zero or more characters
** Match zero or more directories
? Match a single character
You may also exclude a package and all of its children/subpackages this way:
<exclude>some/package/**/*</exclude>
This will exclude every class in some.package, as well as any children. For example, some.package.child wouldn't be included in the reports either.
I have tested and my report goal reports on a reduced number of classes using the above.
If you are then pushing this report into Sonar, you will then need to tell Sonar to exclude these classes in the display which can be done in the Sonar settings
Settings > General Settings > Exclusions > Code Coverage
Sonar Docs explains it a bit more
Running your command above
mvn clean verify
Will show the classes have been excluded
No exclusions
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) # ** ---
[INFO] Analyzed bundle '**' with 37 classes
With exclusions
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) # ** ---
[INFO] Analyzed bundle '**' with 34 classes
Though Andrew already answered question with details , i am giving code how to exclude it in pom
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<configuration>
<excludes>
<exclude>**/*com/test/vaquar/khan/HealthChecker.class</exclude>
</excludes>
</configuration>
<executions>
<!-- prepare agent for measuring integration tests -->
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
For Springboot application
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- Exclude class from test coverage -->
<exclude>**/*com/khan/vaquar/Application.class</exclude>
<!-- Exclude full package from test coverage -->
<exclude>**/*com/khan/vaquar/config/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
Another solution:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<excludes>
<exclude>com.mypackage1</exclude
<exclude>com.mypackage2</exclude>
</excludes>
<element>PACKAGE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.85</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
Please note that, we are using "<element>PACKAGE</element>" in the configuration which then helps us to exclude at package level.
you can configure the coverage exclusion in the sonar properties, outside of the configuration of the jacoco plugin:
...
<properties>
....
<sonar.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.exclusions>
<sonar.test.exclusions>
src/test/**/*
</sonar.test.exclusions>
....
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.coverage.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.coverage.exclusions>
<jacoco.version>0.7.5.201505241946</jacoco.version>
....
</properties>
....
and remember to remove the exclusion settings from the plugin
Some Examples from the SonarQube Docs:
Use sonar.coverage.exclusions property.
mvn clean install -Dsonar.coverage.exclusions=**/*ToBeExcluded.java
This should exclude the classes from coverage calculation.
This Work Like a charm with Spring Boot 2.5.3 and Jacoco 0.8.4 ^_^
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.4</version>
<configuration>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
<output>file</output>
<append>true</append>
<excludes>
<exclude>**/*com/example/Application.class</exclude>
<exclude>**/*com/example/modal*/**</exclude>
<exclude>**/*com/example/dto*/**</exclude>
<exclude>**/*com/example/mapper*/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
https://github.com/jacoco/jacoco/issues/34
These are the different notations for classes we have:
VM Name: java/util/Map$Entry
Java Name: java.util.Map$Entry File
Name: java/util/Map$Entry.class
Agent Parameters, Ant tasks and Maven prepare-agent goal
includes: Java Name (VM Name also works)
excludes: Java Name (VM Name also works)
exclclassloader: Java Name
These specifications allow wildcards * and ?, where * wildcards any number of characters, even multiple nested folders.
Maven report goal
includes: File Name
excludes: File Name
These specs allow Ant Filespec like wildcards *, ** and ?, where * wildcards parts of a single path element only.
Here is the working sample in pom.xml file.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>target/jacoco-ut</outputDirectory>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>PACKAGE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.00</minimum>
</limit>
</limits>
</rule>
</rules>
<excludes>
<exclude>com/pfj/fleet/dao/model/**/*</exclude>
</excludes>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>

Resources