Skip to content

Measure coverage in CI and gate it - #13

Merged
mmlado merged 1 commit into
mainfrom
ci/coverage-measurement
Sep 29, 2026
Merged

mmlado merged 1 commit into
mainfrom
ci/coverage-measurement

Conversation

@mmlado

@mmlado mmlado commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Measure coverage in CI and gate it

CI measures test coverage and enforces two floors.

Changes

  • pytest-cov>=5.0 added to the dev extra.
  • [tool.coverage.run]: source = ["cryptnox_id_cli"], branch = true.
  • [tool.coverage.report]: show_missing, skip_covered, fail_under = 60.
  • The test job runs pytest -q -m "not real_card" --cov --cov-report=term-missing --cov-report=xml, then a second report over src/cryptnox_id_cli/cli/commands/ with
    --fail-under=36, and uploads coverage.xml from the 3.14 matrix entry.
  • coverage.xml added to .gitignore.
  • README documents the local coverage command; CHANGELOG entry under Unreleased.

Constraints

The floors compare combined coverage, not line coverage. With branch = true,
fail_under is checked against the combined statement-and-branch percentage that
coverage report prints. On this commit that is 60.25% combined, against 64.11% line and
43.62% branch, so both floor numbers read about four points below what a line-coverage floor
with the same name would mean. coverage report --fail-under=64 exits 2 against this data.
Read fail_under = 60 as the combined metric or the suite looks four points better than it is.

--cov is deliberately not in addopts. Putting it there makes a bare pytest fail for
anyone without pytest-cov installed, and slows every local run. CI passes the flags explicitly.

The commands-layer floor is a separate coverage report invocation because coverage.py has
no per-file fail_under. It reads the same data file, so it adds no test time. The command
modules hold 1699 of the 2158 missed statements, which is why they carry a floor of their own.

Both matrix entries are measured. src has no version_info checks or conditional
imports outside already-pragma'd blocks, so 3.10 and 3.14 are expected to report the same
number; a divergence would be worth seeing rather than suppressing.

Verification

ruff check, ruff format --check, mypy, 347 tests, sphinx-build -W --keep-going, and
python -m build all pass. Both floors were negative-tested: raising either by one point
makes the step exit 2.

🤖 Generated with Claude Code

pytest-cov joins the dev extra; [tool.coverage.run] sets the source and
turns on branch coverage; [tool.coverage.report] carries the project floor
so there is one place to edit when ratcheting. The test job gains --cov and
a second, tighter floor over cli/commands/, which holds 1699 of the 2158
missed statements. coverage.xml ships as an artifact from the 3.14 run.

--cov stays out of addopts: a bare `pytest` would then fail for anyone
without pytest-cov installed.

Note that with branch = true both floors compare the combined
statement-and-branch percentage that coverage report prints, not line
coverage alone. Today those are 60.25% combined against 64.11% line and
43.62% branch, so the gate numbers (60 and 36) read four points lower than
a line-coverage floor would.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mmlado
mmlado requested a review from embarquech September 25, 2026 10:37
@mmlado
mmlado merged commit 2602776 into main Sep 29, 2026
12 checks passed
@mmlado
mmlado deleted the ci/coverage-measurement branch September 29, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant