Main Tutorials

Maven – JaCoCo code coverage example

In this article, we will show you how to use a JaCoCo Maven plugin to generate a code coverage report for a Java project.

Tested with

  1. Maven 3.5.3
  2. JUnit 5.3.1
  3. jacoco-maven-plugin 0.8.2
Note
JaCoCo is an actively developed line coverage tool, that is used to measure how many lines of our code are tested.

1. JaCoCo Maven Plugin

1.1 Declare the following JaCoCo plugin in the pom.xml file.

pom.xml

	<plugin>
		<groupId>org.jacoco</groupId>
		<artifactId>jacoco-maven-plugin</artifactId>
		<version>0.8.2</version>
		<executions>
			<execution>
				<goals>
					<goal>prepare-agent</goal>
				</goals>
			</execution>
			<!-- attached to Maven test phase -->
			<execution>
				<id>report</id>
				<phase>test</phase>
				<goals>
					<goal>report</goal>
				</goals>
			</execution>
		</executions>
	</plugin>

It will run the JaCoCo ‘report’ goal during the Maven test phase.

2. Unit Test

2.1 A simple Java code to return a message, and an empty string checking.

MessageBuilder.java

package com.mkyong.examples;

public class MessageBuilder {

    public String getMessage(String name) {

        StringBuilder result = new StringBuilder();

        if (name == null || name.trim().length() == 0) {

            result.append("Please provide a name!");

        } else {

            result.append("Hello " + name);

        }
        return result.toString();
    }

}

2.2 Unit test above class.

TestMessageBuilder.java

package com.mkyong.examples;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestMessageBuilder {

    @Test
    public void testNameMkyong() {

        MessageBuilder obj = new MessageBuilder();
        assertEquals("Hello mkyong", obj.getMessage("mkyong"));

    }

}

2.3 Run mvn test, the JaCoCo code coverage report will be generated at target/site/jacoco/*

Terminal

$ mvn clean test

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.mkyong.examples.TestMessageBuilder
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.012 s - in com.mkyong.examples.TestMessageBuilder
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.2:report (report) @ maven-code-coverage ---
[INFO] Loading execution data file D:\maven-examples\maven-code-coverage\target\jacoco.exec
[INFO] Analyzed bundle 'maven-code-coverage' with 1 classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.164 s
[INFO] Finished at: 2018-11-14T16:48:39+08:00
[INFO] ------------------------------------------------------------------------

2.4 Open the target/site/jacoco/index.html file, review the code coverage report :

  1. Green – Code is tested or covered.
  2. Red – Code is not tested or covered.
  3. Yellow – Code is partially tested or covered.

3. Improving the Unit Test

3.1 Adding one more test for the red line.

TestMessageBuilder.java

package com.mkyong.examples;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestMessageBuilder {

    @Test
    public void testNameMkyong() {

        MessageBuilder obj = new MessageBuilder();
        assertEquals("Hello mkyong", obj.getMessage("mkyong"));

    }

	@Test
    public void testNameEmpty() {

        MessageBuilder obj = new MessageBuilder();
        assertEquals("Please provide a name!", obj.getMessage(" "));

    }
}

Review the report again.

Terminal

$ mvn clean test

target/site/jacoco/index.html

3.2 Add one more test for the yellow line if condition.

TestMessageBuilder.java

package com.mkyong.examples;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestMessageBuilder {

    @Test
    public void testNameMkyong() {

        MessageBuilder obj = new MessageBuilder();
        assertEquals("Hello mkyong", obj.getMessage("mkyong"));

    }

    @Test
    public void testNameEmpty() {

        MessageBuilder obj = new MessageBuilder();
        assertEquals("Please provide a name!", obj.getMessage(" "));

    }

    @Test
    public void testNameNull() {

        MessageBuilder obj = new MessageBuilder();
        assertEquals("Please provide a name!", obj.getMessage(null));

    }

}

Review the report again.

Terminal

$ mvn clean test

target/site/jacoco/index.html

Finally, all lines are tested, 100% coverage.

4. FAQs

4.1 Make sure lines coverage must meet the minimum 90%.

pom.xml

	<plugin>
		<groupId>org.jacoco</groupId>
		<artifactId>jacoco-maven-plugin</artifactId>
		<version>${jacoco.version}</version>
		<executions>
			<execution>
				<goals>
					<goal>prepare-agent</goal>
				</goals>
			</execution>
			<execution>
				<id>jacoco-report</id>
				<phase>test</phase>
				<goals>
					<goal>report</goal>
				</goals>
			</execution>
			<!-- Add this checking -->
			<execution>
				<id>jacoco-check</id>
				<goals>
					<goal>check</goal>
				</goals>
				<configuration>
					<rules>
						<rule>
							<element>PACKAGE</element>
							<limits>
								<limit>
									<counter>LINE</counter>
									<value>COVEREDRATIO</value>
									<minimum>0.9</minimum>
								</limit>
							</limits>
						</rule>
					</rules>
				</configuration>
			</execution>
			
		</executions>
	</plugin>

The jacoco:check goal is attached to Maven verify phase.

Terminal

$ mvn clean verify

[INFO] Analyzed bundle 'maven-code-coverage' with 1 classes
[WARNING] Rule violated for package com.mkyong.examples: lines covered ratio is 0.8, but expected minimum is 0.9
Note
More JaCoCo check examples :

4.2 How to update the default JaCoCo output folder?

pom.xml

	<plugin>
		<groupId>org.jacoco</groupId>
		<artifactId>jacoco-maven-plugin</artifactId>
		<version>${jacoco.version}</version>
		<executions>
			<execution>
				<goals>
					<goal>prepare-agent</goal>
				</goals>
			</execution>
			<execution>
				<id>jacoco-report</id>
				<phase>test</phase>
				<goals>
					<goal>report</goal>
				</goals>
				<!-- default target/jscoco/site/* -->
				<configuration>
					<outputDirectory>target/jacoco-report</outputDirectory>
				</configuration>
			</execution>
		</executions>
	</plugin>

Download Source Code

$ git clone https://github.com/mkyong/maven-examples.git
$ cd maven-code-coverage

$ mvn clean test
# view report at ‘target/site/jacoco/index.html’

References

  1. Wikipedia : Java code coverage tools
  2. JaCoCo Java Code Coverage Library
  3. JaCoCo in Eclipse IDE

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
16 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
robert
4 years ago

I get the below error. I am using Maven 3.6.1, Java 8, Jacoco plugin 0.8.3 (but same error for 0.8.2)

INFO] — jacoco-maven-plugin:0.8.3:report (report) @ RRC —
[INFO] Loading execution data file /Users/acme/dev/src/gitlab/acme/abc/target/jacoco.exec
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 7.519 s
[INFO] Finished at: 2019-05-03T11:48:26+01:00
[INFO] ————————————————————————
[ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.3:report (report) on project ABC: An error has occurred in JaCoCo report generation.: Error while creating report: Error while analyzing /Users/acme/dev/src/gitlab/acme/abc/target/classes/docs/ABC Release Statement.odt. unexpected EOF -> [Help 1]
[ERROR]

EnriqueSF
3 years ago
Reply to  robert
chris
4 years ago

Worked perfectly. This is the best documentation I’ve seen for jacoco around. You would think that the dolts who wrote the code would document how to use their coverage tool.

Arya
3 years ago
Reply to  chris

Did u get the code coverage? I got the reports but code coverage is 0. In eclipse it is showing above 90%.

Pat
5 years ago

Error : The POM for org.jacoco:jacoco-maven-plugin:jar:0.8.2 is missing,

Pankaj
2 years ago

How can we use JaCoCo Maven Plugin with mockito. I am using JaCoCo maven plugin in my Spring Boot Application with Mockito but I am always getting 0% coverage.
Can you please help me on this.

ananthi
2 years ago

Hi .It is only showing for main java file .Not compiling the test java file .Kindly help

surbhi
2 years ago

Failure to transfer org.jacoco:jacoco-maven-plugin:pom:0.8.2 from https://artifacts.mastercard.int/artifactory/maven-all was cached in 
 the local repository, resolution will not be reattempted until the update interval of public-snapshots has elapsed or updates are forced. 
 Original error: Could not transfer artifact org.jacoco:jacoco-maven-plugin:pom:0.8.2 from/to snapshots (https://artifacts.mastercard.int/
 artifactory/maven-all): sun.security.validator.ValidatorException: PKIX path building failed: 
 sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I get above error in pom while running this application

Issic
2 years ago

What would be the goal command to run jacoco for one specific test case? the Maven test command in 2.3 will run all testcases which in my case is hundreds.

Arya
3 years ago

Followed the tutorial. Report generated but code coverage is showing as zerop. Any idea?

omprasad
3 years ago

[INFO] Scanning for projects…
[INFO]
[INFO] ———————————————————-
[INFO] Building demo1 0.0.1-SNAPSHOT
[INFO] ——————————–[ jar ]———————————
[INFO]
[INFO] — jacoco-maven-plugin:0.8.2:prepare-agent (default) @ demo1 —
[INFO] argLine set to -javaagent:C:\\Users\\Admin\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.8.2\\org.jacoco.agent-0.8.2-runtime.jar=destfile=D:\\algoshack_development\\AlgoAfScripts_02042020_1226\\demo1\\target\\jacoco.exec
[INFO]
[INFO] — maven-resources-plugin:2.6:resources (default-resources) @ demo1 —
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] — maven-compiler-plugin:3.1:compile (default-compile) @ demo1 —
[INFO] Nothing to compile – all classes are up to date
[INFO]
[INFO] — maven-resources-plugin:2.6:testResources (default-testResources) @ demo1 —
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] — maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo1 —
[INFO] Changes detected – recompiling the module!
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 3 source files to D:\algoshack_development\AlgoAfScripts_02042020_1226\demo1\target\test-classes
[INFO]
[INFO] — maven-surefire-plugin:2.12.4:test (default-test) @ demo1 —
[INFO] Surefire report directory: D:\algoshack_development\AlgoAfScripts_02042020_1226\demo1\target\surefire-reports

——————————————————-
T E S T S
——————————————————-
Running demo2.Test2
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.096 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] — jacoco-maven-plugin:0.8.2:report (report) @ demo1 —
[INFO] Loading execution data file D:\algoshack_development\AlgoAfScripts_02042020_1226\demo1\target\jacoco.exec
[INFO] Analyzed bundle ‘demo1’ with 0 classes
[INFO]
[INFO] — maven-jar-plugin:2.4:jar (default-jar) @ demo1 —
[INFO] Building jar: D:\algoshack_development\AlgoAfScripts_02042020_1226\demo1\target\demo1-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] — maven-install-plugin:2.4:install (default-install) @ demo1 —
[INFO] Installing D:\algoshack_development\AlgoAfScripts_02042020_1226\demo1\target\demo1-0.0.1-SNAPSHOT.jar to C:\Users\Admin\.m2\repository\Demo\demo1\0.0.1-SNAPSHOT\demo1-0.0.1-SNAPSHOT.jar
[INFO] Installing D:\algoshack_development\AlgoAfScripts_02042020_1226\demo1\pom.xml to C:\Users\Admin\.m2\repository\Demo\demo1\0.0.1-SNAPSHOT\demo1-0.0.1-SNAPSHOT.pom
[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 2.877 s
[INFO] Finished at: 2020-04-28T20:03:53+05:30
[INFO] ————————————————————————

Rares Cristea
3 years ago

Hello!

I’ve followed your tutorial, but for some reason, my report doesn’t inlude line by line coverage. I can see for each function the percentage of coverage, but I cannot click on it to see my java code as it was covered by the tests. Any help ?

Thank you!

Adina
3 years ago

Excellent tutorial! Works without any problems with the latest JaCoCo version, 0.8.5. Thank you!

Pat
5 years ago

not working i get:

[WARNING] The POM for org.jacoco:jacoco-maven-plugin:jar:0.8.2 is missing, no dependency information available
[WARNING] Error injecting: org.jacoco.maven.AgentMojo
java.lang.NoClassDefFoundError: org/jacoco/core/runtime/AgentOptions
[ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.2:prepare-agent (default)
Execution default of goal org.jacoco:jacoco-maven-plugin:0.8.2:prepare-agent failed: A required class was missing while executing org.jacoco:jacoco-maven-plugin:0.8.2:prepare-agent: org/jacoco/core/runtime/AgentOptions

Yam
3 years ago
Reply to  Pat

Do you had any solution for this error?

Venkatesh Kadali
4 years ago

I want Jacoco to generate reports even if the build fails.