Measuring SpringBoot Test Coverage with JaCoCo: Configuration and Best Practices
This guide explains how to integrate JaCoCo into SpringBoot projects using Maven or Gradle, generate detailed HTML and XML coverage reports, interpret line, branch, and method metrics, exclude irrelevant code, set coverage thresholds, and address common pitfalls to ensure thorough testing of critical business logic.
1. What is Code Coverage? What JaCoCo Can Do
Code coverage is the percentage of code lines executed by test cases. High coverage does not guarantee test quality, while low coverage indicates missing tests. The goal is 100% coverage for critical business code, with relaxed standards for non‑essential utilities.
1.1 Definition
Coverage = executed lines / total lines. High coverage alone does not ensure quality; low coverage always signals gaps.
1.2 Core Features of JaCoCo
JaCoCo is an open‑source Java coverage tool. Its main advantages are:
Non‑intrusive integration (no changes to business code)
Simple configuration (quickly added to SpringBoot projects)
Intuitive reports (HTML visualisation of uncovered code)
It provides several coverage metrics: line, branch, method, class, and instruction.
2. Integrating JaCoCo into a SpringBoot Project
2.1 Maven Dependency and Plugin
The SpringBoot test starter already contains JaCoCo components, so only the plugin needs to be added in pom.xml:
<!-- spring-boot-starter-test already includes JaCoCo core components -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- JaCoCo Maven plugin (generates the report) -->
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/jacoco-report</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>Key points:
Use JaCoCo version 0.8.5+ for SpringBoot 2.x/3.x compatibility.
Default report directory is target/site/jacoco; can be changed via outputDirectory.
Both prepare-agent and report executions are required.
2.2 Gradle Configuration
For Gradle projects, add the plugin and enable reporting:
// Apply plugins
plugins {
id 'org.springframework.boot' version '2.7.10'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
id 'jacoco' // JaCoCo plugin
}
// Enable JaCoCo during tests
test {
jacoco {
enabled = true
}
}
// Generate HTML report
jacocoTestReport {
dependsOn test
reports {
html.enabled = true
xml.enabled = true
csv.enabled = false
html.destination file("${buildDir}/jacoco-report/html")
}
}3. Generating and Interpreting the JaCoCo Report
3.1 Run Tests to Produce Coverage Data
Two ways to trigger data collection:
Maven command : mvn clean test jacoco:report IDE execution : run the test task from IDEA/Eclipse, then run mvn jacoco:report to create the HTML file.
The command sequence cleans previous builds, executes all unit and integration tests, and finally generates the report.
3.2 Report Overview
The HTML report contains four main sections; beginners focus on the first three:
Summary : overall line, branch, and method coverage percentages.
Package/Class list : clickable tree of packages and classes with colour‑coded coverage (green = full, yellow = partial, red = none).
Class detail : line‑by‑line coverage for a selected class; red lines indicate missing tests.
Example: a line coverage of 85 % means 15 % of the code is not exercised by tests.
3.3 Adding Tests for Uncovered Code
Suppose UserService.getUserStatus(Integer age) has an uncovered else branch for age ≥ 60. After locating the red line in the report, add a test case:
@Test
public void testGetUserStatus_Elder() {
// Verify age = 65 triggers the "老年" branch
String status = userService.getUserStatus(65);
Assertions.assertEquals("老年", status);
}Re‑run mvn clean test jacoco:report; the report now shows the branch in green and the overall coverage percentages increase.
4. Advanced JaCoCo Configuration
4.1 Excluding Irrelevant Code
Exclude generated or utility classes to avoid lowering the overall rate:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<configuration>
<excludes>
<exclude>com/example/demo/entity/**/*.class</exclude>
<exclude>com/example/demo/util/**/*.class</exclude>
<exclude>com/example/demo/config/**/*.class</exclude>
<exclude>com/example/demo/DemoApplication.class</exclude>
</excludes>
</configuration>
</plugin>Note that the path uses '/' as the separator, not '.'.
4.2 Defining Coverage Thresholds
Fail the build if coverage falls below the defined minimums (e.g., line ≥ 80 %, branch ≥ 70 %, method ≥ 85 %):
<plugin>
...
<executions>
<execution>
<id>check</id>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>CLASS</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.8</minimum>
</limit>
<limit>
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.7</minimum>
</limit>
<limit>
<counter>METHOD</counter>
<value>COVEREDRATIO</value>
<minimum>0.85</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>If the thresholds are not met, mvn test aborts with an error, forcing developers to add missing tests.
4.3 Generating XML for CI/CD
Configure the report to output both HTML and XML so that tools like Jenkins can consume the data:
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/jacoco-report</outputDirectory>
<formats>
<format>HTML</format>
<format>XML</format>
</formats>
</configuration>
</execution>5. Common Pitfalls
Missing jacoco.exec : run tests before generating the report.
Empty classes/methods in report : check that tests actually hit the code and that exclude patterns are correct.
Coverage stays at 0 % : ensure the prepare-agent execution is present and tests are not ignored.
Branch coverage never reaches 100 % : add tests for all conditional branches and exception paths.
JaCoCo fails with SpringBoot 3.x : upgrade JaCoCo to 0.8.8 or newer.
Exclude patterns not applied : use '/' separators (e.g., com/example/demo/entity/**/*.class).
6. Conclusion
JaCoCo is the most practical coverage tool for SpringBoot applications. Its non‑intrusive integration, simple configuration, and visual reports help developers pinpoint testing gaps, improve test completeness, and maintain higher code quality without chasing an unrealistic 100 % coverage target.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Workshop
Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
