Add CI test-coverage gate at 80% #34

Merged
willemjan merged 1 commits from feature/ci-coverage-gate into feature/pdf-report-redesign 2026-09-05 20:56:20 +00:00
Owner

Summary

Stacked on #31 (base branch is feature/pdf-report-redesign) — merge last, after #29/#30/#31, or retarget to main once those land. This is PR 4/4 of the insulin-profile/treatment-overlay/report-redesign/CI work.

  • requirements.txt + pyproject.toml: pytest-cov, [tool.coverage.run] (omits app.py/pages/*/tests/*), [tool.coverage.report] fail_under = 80.
  • .gitea/workflows/pipeline.yml: the test job now runs pytest --cov=. --cov-report=xml (fails the build below 80%), uploads coverage.xml as a build artifact; the sonarqube job downloads it so Sonar gets real coverage data — closes the gap homelab-cicd-werkinstructie.md already flagged as a known future task.
  • sonar-project.properties: added sonar.python.coverage.reportPaths=coverage.xml.
  • Backfilled a few genuine gaps in ui_common.py (get_colors()'s theme-fallback branch, the secondary_y=True overlay-trace branches) — now 100%.
  • Added # pragma: no cover (with an inline rationale comment) to the handful of functions in ui_common.py/auth.py that are themselves thin Streamlit-widget orchestration (select_period_days, load_range_data, load_profile, render_completeness_warning, render_event_level, require_auth) — same reasoning as excluding pages/*.py: they're UI wiring around logic that's already fully tested (verify_password, completeness_warning, detect_events, etc.).
  • .gitignore/.dockerignore: exclude .coverage/coverage.xml.

Scope note: main doesn't have the Jenkins/OpenShift files from the experimental open-shift-test branch (verified when starting this work — that branch was never merged), so there was nothing to remove there; this PR only touches the existing Gitea Actions pipeline.

Coverage result

Measured modules (reporting.py, nightscout_client.py, data_processing.py, pdf_export.py, profile_data.py, ui_common.py, auth.py) are at 98.44% — well above the 80% gate. The remaining ~14 uncovered lines are defensive guard clauses (e.g. malformed-input fallbacks) that are unreachable in practice given the current call graph; chasing literal 100% there would mean testing private helpers with contrived inputs rather than real behavior, which didn't seem worth it given the large margin already achieved.

Test plan

  • ruff check . passes
  • pytest tests/ --cov=. --cov-report=term-missing passes the 80% gate (98.44% actual) — 145 tests total
  • Manually ran the full app (all 9 pages: Live, Samenvatting, AGP Profiel, Dagoverzicht, Hypo/Hyper Events, Trends, Export, Insulineprofiel) end-to-end after these changes — no tracebacks, auth.py/ui_common.py changes are comments/pragmas only so behavior is unchanged
  • Not yet verified: the actual Gitea Actions run on the real act_runner (artifact upload/download between test and sonarqube jobs) — this repo's own CI history shows act_runner has version-specific quirks with some actions (see the Trivy pinning comment in pipeline.yml), so worth watching the first real run of this pipeline change

🤖 Generated with Claude Code

## Summary Stacked on #31 (base branch is `feature/pdf-report-redesign`) — merge last, after #29/#30/#31, or retarget to `main` once those land. This is PR 4/4 of the insulin-profile/treatment-overlay/report-redesign/CI work. - `requirements.txt` + `pyproject.toml`: `pytest-cov`, `[tool.coverage.run]` (omits `app.py`/`pages/*`/`tests/*`), `[tool.coverage.report] fail_under = 80`. - `.gitea/workflows/pipeline.yml`: the `test` job now runs `pytest --cov=. --cov-report=xml` (fails the build below 80%), uploads `coverage.xml` as a build artifact; the `sonarqube` job downloads it so Sonar gets real coverage data — closes the gap `homelab-cicd-werkinstructie.md` already flagged as a known future task. - `sonar-project.properties`: added `sonar.python.coverage.reportPaths=coverage.xml`. - Backfilled a few genuine gaps in `ui_common.py` (`get_colors()`'s theme-fallback branch, the `secondary_y=True` overlay-trace branches) — now 100%. - Added `# pragma: no cover` (with an inline rationale comment) to the handful of functions in `ui_common.py`/`auth.py` that are themselves thin Streamlit-widget orchestration (`select_period_days`, `load_range_data`, `load_profile`, `render_completeness_warning`, `render_event_level`, `require_auth`) — same reasoning as excluding `pages/*.py`: they're UI wiring around logic that's already fully tested (`verify_password`, `completeness_warning`, `detect_events`, etc.). - `.gitignore`/`.dockerignore`: exclude `.coverage`/`coverage.xml`. **Scope note:** `main` doesn't have the Jenkins/OpenShift files from the experimental `open-shift-test` branch (verified when starting this work — that branch was never merged), so there was nothing to remove there; this PR only touches the existing Gitea Actions pipeline. ## Coverage result Measured modules (`reporting.py`, `nightscout_client.py`, `data_processing.py`, `pdf_export.py`, `profile_data.py`, `ui_common.py`, `auth.py`) are at **98.44%** — well above the 80% gate. The remaining ~14 uncovered lines are defensive guard clauses (e.g. malformed-input fallbacks) that are unreachable in practice given the current call graph; chasing literal 100% there would mean testing private helpers with contrived inputs rather than real behavior, which didn't seem worth it given the large margin already achieved. ## Test plan - [x] `ruff check .` passes - [x] `pytest tests/ --cov=. --cov-report=term-missing` passes the 80% gate (98.44% actual) — 145 tests total - [x] Manually ran the full app (all 9 pages: Live, Samenvatting, AGP Profiel, Dagoverzicht, Hypo/Hyper Events, Trends, Export, Insulineprofiel) end-to-end after these changes — no tracebacks, `auth.py`/`ui_common.py` changes are comments/pragmas only so behavior is unchanged - [ ] Not yet verified: the actual Gitea Actions run on the real `act_runner` (artifact upload/download between `test` and `sonarqube` jobs) — this repo's own CI history shows act_runner has version-specific quirks with some actions (see the Trivy pinning comment in `pipeline.yml`), so worth watching the first real run of this pipeline change 🤖 Generated with [Claude Code](https://claude.com/claude-code)
willemjan added 1 commit 2026-09-05 20:52:49 +00:00
Add CI test-coverage gate at 80%, backfill remaining logic-module gaps
willemjan/glucose-dashboard/pipeline/head This commit looks good
7f4377329a
pytest-cov + pyproject.toml [tool.coverage.*] measure reporting.py,
nightscout_client.py, data_processing.py, pdf_export.py, profile_data.py,
ui_common.py, and auth.py; app.py and pages/*.py are omitted (thin
Streamlit UI scripts, not meaningfully unit-testable without a running
Streamlit session — the handful of similarly UI-coupled functions left
in ui_common.py/auth.py are marked "# pragma: no cover" with the same
rationale, since the logic they call into is already fully tested).

The Gitea Actions test job now runs with --cov and fails the build
below 80%; the coverage XML is uploaded as a build artifact and fed
into the SonarQube scan (closing the gap flagged in
homelab-cicd-werkinstructie.md). Backfilled a few missing branches
(get_colors() theme fallback, secondary-y-axis overlay traces) to reach
98% on the measured modules — comfortable headroom above the 80% gate.

Builds on #29/#30/#31.
willemjan merged commit a4d29e85a8 into feature/pdf-report-redesign 2026-09-05 20:56:20 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: willemjan/glucose-dashboard#34