Test Coverage Monitoring
This project uses fully open-source tools for test coverage monitoring — no paid services or proprietary platforms required.
Overview
| Component | Test Framework | Coverage Tool | Report Format |
|---|---|---|---|
| C++ (core) | doctest | GCC --coverage + lcov/genhtml | HTML artifact |
| Python (GUI) | pytest | pytest-cov (coverage.py) | HTML artifact |
| JS (webservice) | shell scripts | *(not yet instrumented)* | — |
How It Works
C++ Unit Test Coverage
The C++ tests use GCC's built-in profiling instrumentation:
- Build with coverage: CMake option
-DENABLE_TEST_COVERAGE=1adds-fprofile-arcs -ftest-coveragecompiler/linker flags to both the test binary and thelibgtoptlibrary. - Run tests:
ctestexecutes the doctest-based test binary, which writes.gcdaprofile data files. - Collect with lcov: The
lcovtool reads.gcda/.gcnofiles and produces acoverage.infotracefile. The--rc geninfo_unexecuted_blocks=1flag suppresses false warnings about unexecuted blocks in system headers. - Filter: External code (system headers, third-party libraries, test files) is removed from the tracefile.
- Generate HTML:
genhtmlconverts the tracefile into a browsable HTML report with per-file/per-function/per-branch line coverage.
The HTML report is uploaded as a GitHub Actions artifact named cpp-coverage-report with 30-day retention.
Python Test Coverage
Python tests use pytest-cov, which wraps the standard coverage.py library:
- Run with coverage:
pytest --cov=guiservice --cov-report=html - Upload: HTML report uploaded as python-guiservice-coverage-report artifact.
Coverage Summary
Each CI run writes a coverage summary to the GitHub Actions Job Summary (visible on the workflow run page), so you can see the line/function coverage percentages without downloading the full report.
Latest analyzed run (PR #69)
From merged PR **#69** workflow runs:
- Ubuntu run
22163250333(artifact:cpp-coverage-report)- lines: 70.3% (3099/4410)
- functions: 75.7% (1295/1710)
- branches: 33.6% (1887/5618)
- Guiservice run
22163250340(artifact:python-guiservice-coverage-report)- total: 59.4% (507/854 lines covered)
guiservice/app.py: 84.3%guiservice/gtopt_gui.py: 41.3%guiservice/gtopt_guisrv.py: 0.0%
Lowest C++ per-file line coverage in the same run:
source/line_lp.cpp: 3.9%source/linear_problem.cpp: 4.7%source/demand_lp.cpp: 5.7%source/capacity_object_lp.cpp: 6.4%source/converter_lp.cpp: 6.4%
Viewing Reports
From GitHub Actions
- Navigate to the Actions tab in the repository.
- Select the workflow run for your branch or PR.
- Scroll to the Artifacts section at the bottom.
- Download the desired coverage report (e.g.,
cpp-coverage-report). - Extract the archive and open
index.htmlin your browser.
Locally (C++)
# Configure with coverage (instruments both tests and libgtopt) cmake -Stest -Bbuild -DENABLE_TEST_COVERAGE=1 -DCMAKE_BUILD_TYPE=Debug # Build and test cmake --build build -j$(nproc) cd build && ctest && cd .. # Collect coverage # --ignore-errors mismatch,mismatch: suppress third-party header mismatch warnings # --ignore-errors unexecuted,unexecuted: suppress unexecuted block warnings # --rc unexecuted_blocks=1: zero out counts on unexecuted non-branch lines lcov --capture --directory build --output-file coverage.info \ --gcov-tool gcov-14 \ --ignore-errors mismatch,mismatch \ --ignore-errors unexecuted,unexecuted \ --rc unexecuted_blocks=1 lcov --remove coverage.info '/usr/*' '*/cpm_modules/*' '*/test/*' \ '*/daw/*' '*/strong_type/*' '*/spdlog/*' \ --output-file coverage.info --rc branch_coverage=1 # Generate HTML report with branch coverage genhtml coverage.info --output-directory coverage-report \ --rc branch_coverage=1 # Open coverage-report/index.html
Locally (Python)
pip install pytest pytest-cov -r guiservice/requirements.txt python -m pytest guiservice/tests/ --cov=guiservice --cov-report=html:coverage-guiservice # Open coverage-guiservice/index.html
Tools Used
All tools are free and open-source:
| Tool | License | Purpose |
|---|---|---|
| GCC | GPL-3.0 | C++ compiler with --coverage support |
| lcov | GPL-2.0 | GCC coverage data collection/filtering |
| genhtml | GPL-2.0 | HTML coverage report generation |
| coverage.py | Apache-2.0 | Python code coverage measurement |
| pytest-cov | MIT | pytest plugin for coverage.py |
Future Improvements
- Add coverage trend tracking using GitHub Pages or artifact comparison scripts.
- Instrument the Node.js webservice tests (e.g., via c8 or nyc).
- Add coverage thresholds to fail the build if coverage drops below a minimum.
- Add PR comment with coverage diff using a lightweight open-source GitHub Action.