skip to content

After execution data is collected, how do you produce a human- and CI-readable coverage report with JaCoCo, and what formats matter?

level: juniorimportance: should knowfreq 50%

answer

  1. report reads jacoco.exec + classes + sources
  2. HTML for humans, XML for Sonar/CI
  3. target/site/jacoco
  4. report never fails build
  5. counters: line/branch/instruction

basics

~10 s

Bind the report goal. It reads target/jacoco.exec and your compiled classes to emit HTML (for humans) and XML (for CI tools like SonarQube) in target/site/jacoco/.

solid answer

~40 s

The `report` goal converts the binary `jacoco.exec` execution data plus the compiled classes and sources into readable output. By default it produces HTML, XML, and CSV under `target/site/jacoco/`. HTML is for developers; XML is what coverage aggregators (SonarQube, Codecov, Coveralls) parse. You bind it to a phase after tests run — commonly `test` (so it runs in the unit-test cycle) or `verify`. It needs both the `.exec` file and the classes/sources to map execution counts back to lines, so it must run in the same module after compilation and testing. report only summarizes — it never fails the build on low coverage; that's the `check` goal's job.

code

bash · 3 lines
bash
mvn clean test
# produces target/jacoco.exec then target/site/jacoco/index.html (HTML)
# and target/site/jacoco/jacoco.xml (for SonarQube/Codecov)

go deeper

for a junior

Knows the report goal makes the HTML report you open in a browser.

for a middle

Knows it also emits XML for CI tools and that it needs the .exec file plus classes/sources.

for a senior

Distinguishes report (descriptive) from check (enforcing) and wires separate reports for unit vs integration coverage.

for a principal

Defines org-wide reporting/XML conventions feeding a central quality gate (SonarQube), not per-developer HTML inspection.

## Purpose of the report goal `prepare-agent` collects raw counts into `target/jacoco.exec`. That binary file is useless to humans. The `report` goal reads it together with the module's compiled classes and source files and produces formatted reports. ## What it needs To turn an execution count into 'line 42 of OrderService was hit 3 times', JaCoCo needs: - the `.exec` data file, - the compiled bytecode (to know line numbers), - the source files (to render annotated HTML). So `report` must run in the same module, after compile + test. ## Output formats (target/site/jacoco/) - **HTML** (`index.html`) — interactive, drill-down per package/class/line. For developers. - **XML** (`jacoco.xml`) — machine-readable; consumed by SonarQube, Codecov, Coveralls, Jenkins plugins. - **CSV** — simple tabular summary. ## Binding ```xml <execution> <id>report</id> <phase>test</phase> <goals><goal>report</goal></goals> </execution> ``` Binding to `test` runs it right after unit tests. For integration coverage you'd add a second report (often bound to `verify`) using the Failsafe `.exec`. ## Coverage counters JaCoCo measures - INSTRUCTION (bytecode instructions — finest grained) - LINE - BRANCH (if/switch branches) - METHOD, CLASS, COMPLEXITY (cyclomatic) ## Key distinction `report` is descriptive only. It will happily report 12% coverage and let the build pass. Enforcing a minimum is a separate goal (`check`).

  • Which output format do CI coverage services consume, and why not HTML?
    XML (jacoco.xml). HTML is layout for humans; XML is structured data that tools like SonarQube and Codecov can parse reliably.
  • Does the report goal fail the build when coverage is low?
    No. report only renders results; enforcing thresholds is done by the check goal with coverage rules.

saying these in an interview costs you the question

  • Believing report enforces a coverage minimum
  • Forgetting report needs compiled classes + sources in the same module
  • Confusing HTML with the machine-readable XML for CI

context