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: Jacoco coverage report

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.

Jacoco coverage 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

  1. Maven build lifecycle Maven goals and execution order explained
  2. Jacoco offical page