When I started using Java 7, I noticed right away that the Cobertura Maven plugin doesn’t support it. This was a huge problem to me because I used code coverage reports every day.
I did some research and found the JaCoCo code coverage library. It looked interesting and I decided to give it a shot.
The problem was that configuring it was really hard and took a lot of time. I read numerous tutorials just to find out that the instructions given in them did not work for me. Then I ran into this blog post and everything fall into place.
Although that blog post was extremely valuable to me, it is a bit vague. I felt that a more detailed explanation about the usage of the JaCoCo Maven plugin would be valuable.
This blog post describes how we can create code coverage reports for unit and integration tests by using the JaCoCo Maven plugin.
The requirements of our build are following:
- Our build must create code coverage reports for both unit and integration tests when the tests are run.
- The code coverage reports must be created in separate directories. In other words, the code coverage report for unit tests must be created into a different directory than the code coverage report for integration tests.
Let’s get started.
Note: The example application of this blog post is based on the example application of my blog post called Integration Testing with Maven. If you have not read it yet, I recommend that you read it before reading this blog post.
Configuring The JaCoCo Maven Plugin
We use the JaCoCo Maven plugin for two purposes:
- It provides us an access to the JaCoCo runtime agent which records execution coverage data.
- It creates code coverage reports from the execution data recorded by the JaCoCo runtime agent.
We can configure the JaCoCo Maven plugin by following these steps:
- Add the JaCoCo Maven plugin to the plugins section of our POM file.
- Configure the code coverage report for unit tests.
- Configure the code coverage report for integration tests.
These steps are described with more details in the following.
Adding The JaCoCo Maven Plugin to The POM File
We can add the JaCoCo Maven plugin to our POM file by adding the following plugin declaration to itsplugins section:
1
2
3
4
5
|
<
plugin
>
<
groupId
>org.jacoco</
groupId
>
<
artifactId
>jacoco-maven-plugin</
artifactId
>
<
version
>0.7.5.201505241946</
version
>
</
plugin
>
|
Let’s move on and find out how we can configure the code coverage report for our unit tests.
Configuring The Code Coverage Report for Unit Tests
We can configure the code coverage report for unit tests by adding two executions to the plugin declaration. These executions are described in the following:
- The first execution creates a property which points to the JaCoCo runtime agent. Ensure that the execution data is written to the file target/coverage-reports/jacoco-ut.exec. Set the name of the property to surefireArgLine. The value of this property is passed as a VM argument when our unit tests are run.
- The second execution creates the code coverage report for unit tests after unit tests have been run. Ensure that the execution data is read from the file target/coverage-reports/jacoco-ut.exec and that the code coverage report is written to the directory target/site/jacoco-ut.
The relevant part of our plugin configuration looks as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
<
plugin
>
<
groupId
>org.jacoco</
groupId
>
<
artifactId
>jacoco-maven-plugin</
artifactId
>
<
version
>0.7.5.201505241946</
version
>
<
executions
>
<!--
Prepares the property pointing to the JaCoCo runtime agent which
is passed as VM argument when Maven the Surefire plugin is executed.
-->
<
execution
>
<
id
>pre-unit-test</
id
>
<
goals
>
<
goal
>prepare-agent</
goal
>
</
goals
>
<
configuration
>
<!-- Sets the path to the file which contains the execution data. -->
<
destFile
>${project.build.directory}/coverage-reports/jacoco-ut.exec</
destFile
>
<!--
Sets the name of the property containing the settings
for JaCoCo runtime agent.
-->
<
propertyName
>surefireArgLine</
propertyName
>
</
configuration
>
</
execution
>
<!--
Ensures that the code coverage report for unit tests is created after
unit tests have been run.
-->
<
execution
>
<
id
>post-unit-test</
id
>
<
phase
>test</
phase
>
<
goals
>
<
goal
>report</
goal
>
</
goals
>
<
configuration
>
<!-- Sets the path to the file which contains the execution data. -->
<
dataFile
>${project.build.directory}/coverage-reports/jacoco-ut.exec</
dataFile
>
<!-- Sets the output directory for the code coverage report. -->
<
outputDirectory
>${project.reporting.outputDirectory}/jacoco-ut</
outputDirectory
>
</
configuration
>
</
execution
>
</
executions
>
</
plugin
>
|
Let’s find out how we can configure the code coverage report for our integration tests.
Configuring The Code Coverage Report for Integration Tests
We can configure the code coverage report for integration tests by adding two executions to the plugin declaration. These executions are described in the following:
- This first execution creates a property which points to the JaCoCo runtime agent. Ensure that the execution data is written to the file target/coverage-reports/jacoco-it.exec. Set the name of the property to failsafeArgLine. The value of this property is passed as a VM argument when our integration tests are run.
- Create an execution which creates the code coverage report for integration tests after integration tests have been run. Ensure that the execution data is read from the file target/coverage-reports/jacoco-it.exec and that the code coverage report is written to the directory target/site/jacoco-it.
The relevant part of our plugin configuration looks as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<
plugin
>
<
groupId
>org.jacoco</
groupId
>
<
artifactId
>jacoco-maven-plugin</
artifactId
>
<
version
>0.7.5.201505241946</
version
>
<
executions
>
<!-- The Executions required by unit tests are omitted. -->
<!--
Prepares the property pointing to the JaCoCo runtime agent which
is passed as VM argument when Maven the Failsafe plugin is executed.
-->
<
execution
>
<
id
>pre-integration-test</
id
>
<
phase
>pre-integration-test</
phase
>
<
goals
>
<
goal
>prepare-agent</
goal
>
</
goals
>
<
configuration
>
<!-- Sets the path to the file which contains the execution data. -->
<
destFile
>${project.build.directory}/coverage-reports/jacoco-it.exec</
destFile
>
<!--
Sets the name of the property containing the settings
for JaCoCo runtime agent.
-->
<
propertyName
>failsafeArgLine</
propertyName
>
</
configuration
>
</
execution
>
<!--
Ensures that the code coverage report for integration tests after
integration tests have been run.
-->
<
execution
>
<
id
>post-integration-test</
id
>
<
phase
>post-integration-test</
phase
>
<
goals
>
<
goal
>report</
goal
>
</
goals
>
<
configuration
>
<!-- Sets the path to the file which contains the execution data. -->
<
dataFile
>${project.build.directory}/coverage-reports/jacoco-it.exec</
dataFile
>
<!-- Sets the output directory for the code coverage report. -->
<
outputDirectory
>${project.reporting.outputDirectory}/jacoco-it</
outputDirectory
>
</
configuration
>
</
execution
>
</
executions
>
</
plugin
>
|
That’s it. We have now configured the JaCoCo Maven plugin. Our next step is to configure the Maven Surefire plugin. Let’s find out how we can do this.
Configuring The Maven Surefire Plugin
We use the Maven Surefire plugin to run the unit tests of our example application. Because we want to create a code coverage report for our unit tests, we have to ensure that the JaCoCo agent is running when our unit tests are run. We can ensure this by adding the value of the surefireArgLine property as the value of the argLine configuration parameter.
The configuration of the Maven Surefire plugin looks as follows (the required change is highlighted):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-surefire-plugin</
artifactId
>
<
version
>2.15</
version
>
<
configuration
>
<!-- Sets the VM argument line used when unit tests are run. -->
<
argLine
>${surefireArgLine}</
argLine
>
<!-- Skips unit tests if the value of skip.unit.tests property is true -->
<
skipTests
>${skip.unit.tests}</
skipTests
>
<!-- Excludes integration tests when unit tests are run. -->
<
excludes
>
<
exclude
>**/IT*.java</
exclude
>
</
excludes
>
</
configuration
>
</
plugin
>
|
We are almost done. The only thing left for us to do is to configure the Maven Failsafe plugin. Let’s find out how we can do it.
Configuring The Maven Failsafe Plugin
The integration tests of our example application are run by the Maven Failsafe plugin. Because we want to create a code coverage report for our integration tests, we have to ensure that the JaCoCo agent is running when our integration tests are run. We can do this by adding the value of the failsafeArgLineproperty as the value of the argLine configuration parameter.
The configuration of the Maven Failsafe plugin looks as follows (the required change is highlighted):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-failsafe-plugin</
artifactId
>
<
version
>2.15</
version
>
<
executions
>
<!--
Ensures that both integration-test and verify goals of the Failsafe Maven
plugin are executed.
-->
<
execution
>
<
id
>integration-tests</
id
>
<
goals
>
<
goal
>integration-test</
goal
>
<
goal
>verify</
goal
>
</
goals
>
<
configuration
>
<!-- Sets the VM argument line used when integration tests are run. -->
<
argLine
>${failsafeArgLine}</
argLine
>
<!--
Skips integration tests if the value of skip.integration.tests property
is true
-->
<
skipTests
>${skip.integration.tests}</
skipTests
>
</
configuration
>
</
execution
>
</
executions
>
</
plugin
>
|
Creating Code Coverage Reports
We have now successfully finished the required configuration. Let’s see how we can create code coverage reports for unit and integration tests.
The example application of this blog post has three build profiles which are described in the following:
- The dev profile is used during development and it is the default profile of our build. When this profile is active, only unit tests are run.
- The integration-test profile is used to run integration tests.
- The all-tests profile is used to run both unit and integration tests.
We can create different code coverage reports by running the following commands at command prompt:
- The command mvn clean test runs unit tests and creates the code coverage report for unit tests to the directory target/site/jacoco-ut.
- The command mvn clean verify -P integration-test runs integration tests and creates the code coverage report for integration tests to the directory target/site/jacoco-it.
- The command mvn clean verify -P all-tests runs unit and integration tests and creates code coverage reports for unit and integration tests.
That’s all for today. As always, the example application of this blog post is available at Github.