Inside a violationRules limit, what do the counter and value properties control, and how do they change what gets enforced?
answer
- counter = metric, value = measurement
- INSTRUCTION/LINE/BRANCH/COMPLEXITY/METHOD/CLASS
- COVEREDRATIO default vs MISSEDCOUNT
- BRANCH ratio = strict conditional gate
- MISSEDCOUNT maximum 0 = zero tolerance
basics
~10 scounter picks the metric (INSTRUCTION, LINE, BRANCH, COMPLEXITY, METHOD, CLASS). value picks how it's measured (COVEREDRATIO, MISSEDCOUNT, TOTALCOUNT, etc.). Together with minimum/maximum they define the rule.
solid answer
~40 sEach `limit { }` describes one assertion. `counter` selects which JaCoCo metric to evaluate — `INSTRUCTION` (bytecode instructions, the default and most granular), `LINE`, `BRANCH` (decision branches — good for catching untested conditionals), `COMPLEXITY` (cyclomatic), `METHOD`, or `CLASS`. `value` selects how that counter is expressed: `COVEREDRATIO` (default, a 0.0–1.0 fraction), or absolute counts like `COVEREDCOUNT`, `MISSEDCOUNT`, `TOTALCOUNT`, and `MISSEDRATIO`. You then bound it with `minimum` or `maximum` as a BigDecimal. So `counter="BRANCH", value="COVEREDRATIO", minimum=0.7` means at least 70% of branches covered, while `counter="CLASS", value="MISSEDCOUNT", maximum=0` means no class may be entirely uncovered. Choosing BRANCH over INSTRUCTION makes the gate stricter about conditional logic.
code
kotlin · 16 linestasks.jacocoTestCoverageVerification {
violationRules {
rule {
limit {
counter = "BRANCH"
value = "COVEREDRATIO"
minimum = "0.70".toBigDecimal()
}
limit {
counter = "CLASS"
value = "MISSEDCOUNT"
maximum = "0".toBigDecimal()
}
}
}
}go deeper
Name the default (INSTRUCTION/COVEREDRATIO) and that minimum is a fraction.
Explain each counter and value and pick sensible combinations for a goal.
Argue why BRANCH ratio or CLASS missed-count gates catch real gaps instruction ratio misses.
Define an org standard set of counters and defend it against gaming and false confidence.
## The anatomy of a limit A `limit { }` is a single assertion with three knobs: `counter`, `value`, and a bound (`minimum` or `maximum`). The bounds are `BigDecimal`. ## counter — which metric JaCoCo tracks several counters, from finest to coarsest granularity: - `INSTRUCTION` — individual JVM bytecode instructions. Default; least affected by formatting; very granular. - `LINE` — source lines (requires debug info). Intuitive for humans. - `BRANCH` — branches of `if`/`switch`/`?:` decisions. Best signal that conditional logic is actually exercised. - `COMPLEXITY` — cyclomatic complexity covered. Roughly: number of independent paths tested. - `METHOD` — methods entered at least once. - `CLASS` — classes with at least one executed method. ## value — how to express it - `COVEREDRATIO` (default) — covered / total, a fraction 0.0–1.0. Use with `minimum`. - `MISSEDRATIO` — missed / total. Use with `maximum`. - `COVEREDCOUNT`, `MISSEDCOUNT`, `TOTALCOUNT` — absolute integers. Use `maximum = 0` on `MISSEDCOUNT` for a zero-tolerance rule. ## Putting it together The combination matters. `BRANCH/COVEREDRATIO/minimum=0.70` is a strong rule because branch coverage is hard to game — you must actually exercise both sides of conditionals. `INSTRUCTION/COVEREDRATIO` is the common default headline number. `CLASS/MISSEDCOUNT/maximum=0` forces every class to have *some* coverage, which catches whole files nobody tested. ## Example combining two limits ```kotlin rule { limit { // headline counter = "INSTRUCTION"; value = "COVEREDRATIO"; minimum = "0.80".toBigDecimal() } limit { // no fully-untested class counter = "CLASS"; value = "MISSEDCOUNT"; maximum = "0".toBigDecimal() } } ``` Both limits in one rule must pass for the rule to pass. To enforce different scopes you use separate `rule {}` blocks instead.
- When would you prefer BRANCH coverage over INSTRUCTION coverage in a rule?When you care that conditional logic is actually exercised. High instruction coverage can still leave the false side of an if untested; BRANCH coverage forces both outcomes, so it's a stronger gate for decision-heavy code.
- How do you express a rule like 'no class may be completely untested'?counter = CLASS, value = MISSEDCOUNT, maximum = 0. A class with zero executed methods counts as missed, so any fully-untested class makes the count exceed 0 and fails the rule.
saying these in an interview costs you the question
- Saying COVEREDRATIO takes a percentage like 80 instead of a fraction 0.80.
- Thinking value and counter are interchangeable terms.
- Believing high INSTRUCTION coverage guarantees all branches are tested.