← Back to portfolio

Embedding JaCoCo Coverage Into CI/CD Pipelines: A Practical Guide

JaCoCoCI/CDJavaTestingJenkins

JaCoCo is the standard Java coverage tool. Getting it to produce numbers is easy. Getting those numbers to actually improve code quality requires thought about where in the pipeline it runs, how thresholds are set, and what happens when coverage drops.

The Setup

Adding JaCoCo to Maven builds with the prepare-agent and report goals is straightforward. The agent instruments classes at build time, and the report goal generates XML and HTML output after tests complete. A key configuration choice:

<configuration>
    <excludes>
        <exclude>**/config/**</exclude>
        <exclude>**/dto/**</exclude>
        <exclude>**/*Application.*</exclude>
    </excludes>
</configuration>

Excluding configuration classes, DTOs, and the main application class prevents inflated coverage numbers that do not reflect business logic quality.

The Pipeline Integration

A well-structured pipeline runs JaCoCo in multiple stages:

  1. Unit tests: Fast, runs on every commit. Set a reasonable line coverage threshold.
  2. Integration tests: Slower, runs on PR merge. Set a branch coverage threshold.
  3. Coverage trend: Compares current coverage to the previous build. Fails if coverage drops beyond a small tolerance. This catches the "I'll add tests later" pattern.

The trend check is often the most valuable addition. Absolute thresholds let teams game the system with trivial tests. Trend enforcement means every change must maintain or improve coverage.

The Reporting

Publishing JaCoCo HTML reports as CI artifacts and posting a coverage summary comment on every PR makes coverage visible at review time, not after merge. The comment should show lines covered, branches covered, and which classes have the lowest coverage.

The biggest win is not the numbers. It is the cultural shift. When coverage is visible on every PR, engineers start writing tests before they are asked.