Code coverage reports with Maven and Jacoco
Table of Contents
Today I would like to focus on code coverage. In few steps I will show how to configure Maven to generate code coverage report using Jacoco.
I will present configuration of both unit and integration tests.
Example project
Our project structure looks like this:
> tree
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── codes
│ │ └── hubertwo
│ │ └── maven
│ │ └── coverage
│ │ ├── HelloMessageRepository.java (implementation of repository)
│ │ ├── MessageRepository.java (repository's interface)
│ │ ├── MessageService.java (service which uses repository to get message)
│ │ └── SumService.java (dummy sum service)
│ └── resources
└── test
└── java
└── codes
└── hubertwo
└── maven
└── coverage
├── HelloMessageRepositoryTest.java (unit test)
├── MessageServiceTestIT.java (integration test)
└── SumServiceTest.java - (unit test)
The project contains single pom.xml
file with JUnit5 dependency and no additional configuration.
You can find two Java services and repository under src/main/java
and unit and integration test under src/test/java
.
Check if tests are being executed
Ok so before we generate the coverage report let’s check if test are being executed.
> mvn clean verify
...
[INFO] Running codes.hubertwo.maven.coverage.HelloMessageRepositoryTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 s - in codes.hubertwo.maven.coverage.HelloMessageRepositoryTest
...
[INFO] Running codes.hubertwo.maven.coverage.MessageServiceTestIT
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 s - in codes.hubertwo.maven.coverage.MessageServiceTestIT
[INFO] BUILD SUCCESS
Looks like all test are being executed and passing. We can move to next step.
Generating code coverage report using Jacoco
First we need to add Jacoco’s maven plugin to our pom.xml
file.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
The next step is to run tests and generate coverage report.
mvn clean verify
...
[INFO] --- jacoco-maven-plugin:0.8.7:prepare-agent (default) @ maven-jacoco ---
...
[INFO] Running codes.hubertwo.maven.coverage.SumServiceTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 s - in codes.hubertwo.maven.coverage.SumServiceTest
[INFO] Running codes.hubertwo.maven.coverage.HelloMessageRepositoryTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 s - in codes.hubertwo.maven.coverage.HelloMessageRepositoryTest
...
[INFO] --- jacoco-maven-plugin:0.8.7:report (report) @ maven-jacoco ---
[INFO] Analyzed bundle 'maven-jacoco' with 2 classes
...
[INFO] Running codes.hubertwo.maven.coverage.MessageServiceTestIT
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.059 s - in codes.hubertwo.maven.coverage.MessageServiceTestIT
...
[INFO] BUILD SUCCESS
From logs we can see that Jacoco has been executed. But what exactly has been done? Where we can find the report?
The answer is simple, you can find HTML format report under target/site/jacoco/index.html
.
Simply open the file in any browser. The coverage report should look like this:
Hmmm… from the report we can clearly observe that HelloMessagerepostiry
and SumService
have 100% code coverage,
but MessageService
has 0%. How is this possible? We have integration tests written for the service and
Maven executed them. Why aren’t integration test results included in the report? Let’s fix it!
Including integration tests in the code coverage report
To include integration tests coverage in Jacoco’s coverage report we simply have to add 2 more executions to our plugin configuration.
Let’s open the pom.xml
and add them.
<!-- Coverage for integration tests -->
<execution>
<id>pre-integration-tests</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>after-integration-tests</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
Once done we can run mvn clean verify
again to execute tests and generate the report.
mvn clean verify
...
[INFO] --- jacoco-maven-plugin:0.8.7:prepare-agent (pre-unit-tests) @ maven-jacoco ---
...
[INFO] Running codes.hubertwo.maven.coverage.SumServiceTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.062 s - in codes.hubertwo.maven.coverage.SumServiceTest
[INFO] Running codes.hubertwo.maven.coverage.HelloMessageRepositoryTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 s - in codes.hubertwo.maven.coverage.HelloMessageRepositoryTest
...
[INFO] --- jacoco-maven-plugin:0.8.7:report (after-unit-tests) @ maven-jacoco ---
[INFO] Analyzed bundle 'maven-jacoco' with 3 classes
...
[INFO] --- jacoco-maven-plugin:0.8.7:prepare-agent (pre-integration-tests) @ maven-jacoco ---
[INFO] Running codes.hubertwo.maven.coverage.MessageServiceTestIT
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.048 s - in codes.hubertwo.maven.coverage.MessageServiceTestIT
...
[INFO] --- jacoco-maven-plugin:0.8.7:report (after-integration-tests) @ maven-jacoco ---
The execution steps we have just added are visible in the logs and report has been generated. From now on the integration tests coverage should be included in the report.
TL;DR - Maven Jacoco configuration
You can find the link to repository with example code at the bottom of this page. However, if you are just looking for ready to use solution, you can find full configuration below.
<!-- Code coverage -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<!-- Coverage for unit tests -->
<execution>
<id>pre-unit-tests</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>after-unit-tests</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<!-- Coverage for integration tests -->
<execution>
<id>pre-integration-tests</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>after-integration-tests</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Summary
In this short post we learned how to integrate Jacoco with Maven, generated code coverage report and added the coverage results from integration tests.
Source code
All code samples and Maven project described in this post is available on GitHub
Code coverage report with Maven and Jacoco.
If you found this post useful do not forget to leave a ⭐️ on GitHub :) Thanks!
Read more
- Maven build lifecycle Maven goals and execution order explained
- Jacoco offical page