How do you enforce a minimum coverage threshold in Maven so the build fails when coverage is too low?
answer
- check goal fails build
- rule = element + limits
- counter/value/minimum
- COVEREDRATIO is 0..1 decimal
- bind to verify
- haltOnFailure=false to warn
basics
~10 sBind JaCoCo's check goal and define <rules> with a <limit> — e.g. counter LINE, value COVEREDRATIO, minimum 0.80. If coverage is below the limit, the build fails (typically in the verify phase).
solid answer
~40 sThe `check` goal enforces coverage gates. You configure one or more `<rule>` elements; each has an `<element>` scope (BUNDLE, PACKAGE, CLASS, METHOD) and `<limit>` entries. Each limit names a `<counter>` (INSTRUCTION, LINE, BRANCH, METHOD, CLASS, COMPLEXITY), a `<value>` (COVEREDRATIO, MISSEDCOUNT, COVEREDCOUNT, TOTALCOUNT, MISSEDRATIO), and a `<minimum>` or `<maximum>`. For a ratio like COVEREDRATIO you give a decimal (0.80 = 80%). If any limit is violated the goal fails the build. Bind it to `verify` so it runs after integration tests, and make sure a `report`/exec exists first. You can also use `<excludes>` for generated classes. The classic combo: BUNDLE-level LINE COVEREDRATIO minimum 0.80 plus BRANCH minimum 0.70.
code
xml · 19 lines<execution>
<id>jacoco-check</id>
<phase>verify</phase>
<goals><goal>check</goal></goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>go deeper
Knows the check goal can fail the build below a threshold.
Can write a rule with element/counter/value/minimum and bind it to verify.
Combines BUNDLE + CLASS rules, uses excludes for generated code, and chooses ratio vs count for ratchet strategies.
Sets org-wide coverage policy (which counters, excludes, ratchet vs fixed) and decides haltOnFailure posture per pipeline stage.
## Why check exists `report` is descriptive. To make coverage a build gate you need the `check` goal, which compares measured coverage against rules and **fails the build** when violated. ## Anatomy of a rule Each `<rule>` has: - **`<element>`** — the scope the rule applies to: `BUNDLE` (whole module, the default), `PACKAGE`, `CLASS`, `METHOD`, `SOURCEFILE`. - one or more **`<limit>`** entries. Each `<limit>` has: - **`<counter>`** — what to count: `INSTRUCTION`, `LINE`, `BRANCH`, `METHOD`, `CLASS`, `COMPLEXITY`. - **`<value>`** — the metric: `COVEREDRATIO` (0..1), `MISSEDRATIO`, `COVEREDCOUNT`, `MISSEDCOUNT`, `TOTALCOUNT`. - **`<minimum>`** and/or **`<maximum>`** — the threshold (a decimal like `0.80` for ratios, integer for counts). ## Example ```xml <execution> <id>jacoco-check</id> <phase>verify</phase> <goals><goal>check</goal></goals> <configuration> <rules> <rule> <element>BUNDLE</element> <limits> <limit> <counter>LINE</counter> <value>COVEREDRATIO</value> <minimum>0.80</minimum> </limit> <limit> <counter>BRANCH</counter> <value>COVEREDRATIO</value> <minimum>0.70</minimum> </limit> </limits> </rule> <rule> <element>CLASS</element> <limits> <limit> <counter>LINE</counter> <value>COVEREDRATIO</value> <minimum>0.50</minimum> </limit> </limits> <excludes> <exclude>com.acme.generated.*</exclude> </excludes> </rule> </rules> </configuration> </execution> ``` ## Phase binding Bind to **`verify`** so check runs after both Surefire (unit) and Failsafe (integration) and after the relevant report/exec is available. check itself needs the `.exec` data — prepare-agent must have run earlier in the same build. ## Behavior on violation A violated limit prints e.g. `Rule violated for bundle X: lines covered ratio is 0.62, but expected minimum is 0.80` and fails the build (BUILD FAILURE). Use `<haltOnFailure>false</haltOnFailure>` to warn without failing. ## Practical tips - Per-CLASS rules catch newly-added under-tested classes that a BUNDLE average would hide. - Use `<excludes>` (or the agent's `<excludes>`) for generated code, DTOs, config. - Counts (MISSEDCOUNT maximum) are useful for ratchet strategies.
- Why might a BUNDLE-level 80% rule still let a completely untested class slip in?BUNDLE averages across the whole module, so a large well-tested codebase masks one untested class. Add a CLASS-level rule (e.g. minimum 0.50) to catch per-class gaps.
- How do you make check warn but not fail the build?Set <haltOnFailure>false</haltOnFailure> in the check configuration; it logs violations without failing.
- What value would you use to express 85% as a minimum line coverage?counter LINE, value COVEREDRATIO, minimum 0.85 — ratios are decimals between 0 and 1.
saying these in an interview costs you the question
- Writing minimum as 80 instead of 0.80 for a ratio (treated as 8000%, always fails)
- Binding check before tests/exec exist
- Relying only on BUNDLE averages so per-class gaps hide
- Thinking report enforces thresholds