Java JaCoCo Coverage Backfill (Universal)
When to use
- User asks to add/fix Java tests.
- User asks to improve coverage.
- User asks for branch-gap based supplementary tests.
- Project is Maven or Gradle based.
Goals
- Use JaCoCo XML as the coverage source of truth.
- Track four coverage metrics consistently:
CLASS,METHOD,LINE,BRANCH. - Prioritize classes with worst
BRANCHcoverage for test backfill. - Raise branch quality without causing regression on other coverage dimensions.
Coverage Model
-
CLASS: covered classes / total classes -
METHOD: covered methods / total methods -
LINE: covered lines / total lines -
BRANCH: covered branches / total branches -
Primary backfill target metric:
BRANCH -
Secondary guardrail metrics:
CLASS,METHOD,LINE
Inputs And Defaults
- Class selection: 10 lowest
BRANCH-coverage classes with branch counters. - Default threshold:
BRANCH >= 80%for each selected class. - Secondary constraint: no unexplained regression in
CLASS/METHOD/LINEfor selected classes. - If user provides different thresholds/scope/metric priorities, follow user input.
Important: Where Files Go
| Location | What Goes There |
|---|---|
Skill directory (${HOME}/.codex/skills/java-jacoco-coverage-backfill) | scripts |
Bundled Scripts (Use First)
Scripts are under scripts/ and should be preferred over ad-hoc one-off shell snippets.
scripts/detect_build_tool.sh <repo_or_module_path>- Detect Maven/Gradle and resolve effective build root.
scripts/generate_jacoco_report.sh <repo_or_module_path> [--ignore-test-failures]- Generate JaCoCo XML/HTML reports for Maven or Gradle.
scripts/find_jacoco_reports.sh <repo_or_module_path>- Locate all JaCoCo XML report files in mono-repo/multi-module layouts.
scripts/analyze_jacoco_xml.py --xml <report> --top 10 [--out <snapshot.json>] [--selected <class1,class2,...>]- Produce class ranking (BRANCH asc), module metrics, and optional snapshot JSON for diffing.
scripts/compare_jacoco_snapshots.py --before <baseline.json> --after <post.json> [--selected <class1,class2,...>]- Show metric delta at module and class granularity.
Required workflow
1) Discover project layout
- Detect build system and build root using script:
scripts/detect_build_tool.sh <repo_or_module_path>
- Detect module(s) to analyze:
- Prefer module(s) touched by the task.
- If unspecified, start with the primary module containing Java production code and tests.
2) Ensure JaCoCo is configured (mandatory)
If JaCoCo is missing, add it first.
Maven (if missing)
- Ensure
org.jacoco:jacoco-maven-pluginexists in<build><plugins>. - Required executions:
prepare-agentreport(bound totestphase or invoked viajacoco:report)
Reference snippet:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Gradle (if missing)
- Apply plugin:
id 'jacoco'. - Ensure XML report is enabled.
- Ensure
testfinalizesjacocoTestReport.
Reference snippet (Groovy DSL):
plugins {
id 'java'
id 'jacoco'
}
test {
finalizedBy jacocoTestReport
}
jacocoTestReport {
dependsOn test
reports {
xml.required = true
html.required = true
}
}
3) Generate baseline JaCoCo XML
Use script:
scripts/generate_jacoco_report.sh <repo_or_module_path>
4) Locate JaCoCo XML report(s)
Find candidate XML files:
scripts/find_jacoco_reports.sh <repo_or_module_path>
Selection rules:
- Prefer module-specific report for requested scope.
- If multiple are relevant, analyze per module.
- If only one exists, use it.
5) Analyze coverage with jacoco_reporter_server
For each selected XML report:
- Call
jacoco_reporter_serveron that file (authoritative source for missed line/branch positions). - Use script to compute ranked metrics and baseline snapshot:
python3 scripts/analyze_jacoco_xml.py \
--xml <report_path> \
--top 10 \
--out .coverage/baseline.json
- Rank classes primarily by
BRANCHascending:- primary:
BRANCH%ascending - tie-breaker 1: missed branches descending
- tie-breaker 2:
LINE%ascending
- primary:
- Select top 10 classes with branch counters (or fewer if not available).
- Extract missed branch lines from
jacoco_reporter_serveroranalyze_jacoco_xml.pyoutput. - Preserve baseline snapshot for delta comparison.
6) Design targeted tests
For each selected class:
- Map missed branch lines to concrete conditions.
- Add tests for missing branch directions (
true/false, success/error, allow/deny, found/not-found). - Prefer unit tests first; use integration tests only when branch behavior depends on framework/runtime boundaries.
- Avoid tests that only increase line hits but still miss branch directions.
7) Run tests and iterate
- Run targeted tests first.
- Regenerate JaCoCo XML.
- Re-run
jacoco_reporter_server. - Generate post snapshot and compare:
python3 scripts/analyze_jacoco_xml.py \
--xml <report_path> \
--top 10 \
--out .coverage/post.json
python3 scripts/compare_jacoco_snapshots.py \
--before .coverage/baseline.json \
--after .coverage/post.json
- Repeat until completion criteria are met or blockers are confirmed.
Test design rules
- One test should target one explicit missed-branch intent.
- Use deterministic inputs to force both branch directions.
- Include failure paths (validation, unauthorized, conflict, not found) where relevant.
- Avoid redundant tests that hit same branch direction.
- Keep tests local, readable, and consistent with project conventions.
Multi-module rule
- Do not merge unrelated module coverage into one ranking unless user requests aggregate mode.
- Default: report baseline and post-change per module.
Completion criteria
- For selected class set(s):
- each class reaches
BRANCH >= 80%(or user-defined threshold), and CLASS/METHOD/LINEdo not regress without explanation.
- each class reaches
- If any selected class remains below target, report blockers:
- class name
- current CLASS/METHOD/LINE/BRANCH percentages
- missed branch lines
- why not coverable now
- exact next action needed
Output format (every run)
- Project/build detection summary (Maven/Gradle, module scope).
- JaCoCo setup status:
- already present, or
- added/updated files and config changes.
- Baseline table (selected classes):
- class name
- CLASS%, METHOD%, LINE%, BRANCH%
- covered/missed branch counts
- Added/updated test files list.
- Validation commands and pass/fail status.
- Post-change table for same selected classes with delta columns.
- Module-level summary before/after for CLASS/METHOD/LINE/BRANCH.
- Remaining gaps and concrete next tests (if not complete).
Script-First Commands
scripts/detect_build_tool.sh .
scripts/generate_jacoco_report.sh .
scripts/find_jacoco_reports.sh .
python3 scripts/analyze_jacoco_xml.py --xml <report_path> --top 10 --out .coverage/baseline.json
python3 scripts/analyze_jacoco_xml.py --xml <report_path> --top 10 --out .coverage/post.json
python3 scripts/compare_jacoco_snapshots.py --before .coverage/baseline.json --after .coverage/post.json
Notes
- Do not modify production code only to increase coverage unless user explicitly requests it.
- Coverage decisions must be based on JaCoCo XML +
jacoco_reporter_serveroutput. - If build policy blocks adding JaCoCo, report blocker and required approval explicitly.