Open the HTML report and you get a summary table, one row per routine with branch % and statement %, and a section for triggers below it. Click a routine name for its annotated source, covered lines in green and uncovered lines in red. The numbers come from running the generated tests, so they are measured, not estimated.
A routine can show 100% statement but less than 100% branch when a result-set query has a condition, such as a date range, that no test exercised on both sides. The report names the exact condition.
Rather than leave a line simply red, the report tags it so you know whose problem it is.
| Tag | Meaning | What to do |
|---|---|---|
| D | Dead code. The line can never run, sometimes proven with the contradictory conditions named. | Check your logic. It usually points at a real bug. |
| H | Error-recovery code inside a handler that valid data cannot trigger. Untested by design. | Nobody's bug. |
| E | A tool limit. No sign of dead code; the generator could not drive this line. | An honest gap. Reporting the routine helps close it. |
| Q | A query condition the test data did not exercise on both sides. | Add data that trips it, or confirm the other side is unreachable. |
| BUG | A bug in the function itself. | Fix the function. |
| DDL | A statement that emits DDL. | Review whether it belongs in the routine. |
The counts also appear in the JSON under uncovered_classes, so CI can flag a new suspected-dead branch in a commit.
When a branch cannot be driven without a fabricated or flaky test, it is reported NOT_TESTABLE with a plain reason, for example an error handler reachable only by fault injection, or a non-deterministic path. This is the guarantee in action, a visible gap instead of a false green.
A fresh suite is always green, because the generator records the routine's current output as the expected value. A failure appears later, when the code changes in a way that alters behaviour a test had pinned. Take a classifier that returns 'small' for amounts under 100, then is edited to return 'reduced':
ok 6 - test_classify_amount.test_06_branch_elsif_p_amount_0_true
...
not ok 8 - test_classify_amount.test_08_branch_elsif_p_amount_100_true
# Failed test 8: "branch :: ELSIF p_amount < 100 => TRUE :: returns"
# have: reduced
# want: small
ok 9 - test_classify_amount.test_09_branch_elsif_p_amount_100_false
...
# Looks like you failed 3 tests of 11
Only the tests whose recorded result moved fail. The rest stay green, so a failure points straight at what changed. If the change was intended, re-generate (or accept the new output) and commit the update.