java-coverage · git:20260828.83e1846 · 2026-08-28 · sha256 7b234e2094908d79
java-coverage git:20260828.83e1846A
Immutable. This exact content never changes and is served at /api/v1/blob/7b234e2094908d79.
--- name: java-coverage description: Measure backend test coverage from the terminal — JaCoCo line coverage reported as the exact uncovered lines, and PIT mutation coverage reported as the surviving mutants. Use whenever asked about test coverage, "what isn't tested", "run tests with coverage", uncovered/untested lines or branches, how good the tests are, mutation testing / pitest, or before adding tests to a class — instead of asking the user to click "Run with Coverage" in IntelliJ. --- # Java coverage Two scripts in this skill's own `scripts/` — spell the path from the repo root, since the repo has an unrelated `scripts/` of its own. Both run from anywhere in the repo and print only the **gaps**, as clickable `File.java:12-15,20` refs. ## Line coverage — what never ran ```sh .claude/skills/java-coverage/scripts/coverage.sh # full run, uncovered lines per class .claude/skills/java-coverage/scripts/coverage.sh -n # reuse the last run, don't re-run tests .claude/skills/java-coverage/scripts/coverage.sh -c OwnerMapper -b # one class, incl. half-covered branches ``` JaCoCo is already wired in `petclinic-backend/pom.xml` (agent + report bound to the `test` phase), so a plain `mvn test` writes the very report IntelliJ's "Run with Coverage" shows: `target/site/jacoco/index.html`. `coverage.sh` drives that same `mvn test` and reduces the `jacoco.xml` beside it — it adds the gap extraction, not the instrumentation. ## Mutation coverage — what ran but nothing asserted on ```sh .claude/skills/java-coverage/scripts/mutation.sh rest.error # a package (seconds) .claude/skills/java-coverage/scripts/mutation.sh ValidationErrorExtractor # a class, by simple name .claude/skills/java-coverage/scripts/mutation.sh # everything — minutes, avoid ``` `mutation.sh` is self-contained: PIT is **not** in `pom.xml`. The script resolves the PIT jars from a throwaway POM under `target/pit-work/` and drives PIT's command-line entry point against the module's compiled classes — so nothing in the project changes, and `mvn test` / CI never pay for mutation testing. Keep it that way; do not add `pitest-maven` to the POM. **PIT is slow: always pass a scope.** A package took ~10s, the whole base package takes minutes. By default only the scope's own tests may kill its mutants; `-T` lets the whole suite try (truer score, much slower). `--help` for the rest. Reading the output: `SURVIVED` = a test executed that line but asserted nothing that the mutation broke. `NEVER REACHED` = no test touches it at all — that is a line-coverage hole, fix it with a test before worrying about the mutant. ## Rules - **Never `mvn test` while the IDE is building or running tests.** Both write `target/classes`; the collision fakes `NoClassDefFoundError` and "Unable to find @SpringBootConfiguration" failures that look like real bugs. - **A subset run gives partial coverage** — `coverage.sh -t/--test`, or a bare `mvn test -Dtest=...`. Everything the subset never loads reads as 0%, so the numbers look falsely low. `coverage.sh` labels such a run `PARTIAL` — repeat that label when reporting. - Report the numbers and the gaps. Do not propose a test for every gap: generated code `equals`/`hashCode`/`toString` and accessors are noise, and `coverage.sh` already filters them (`--keep-generated` to see them).