reqcov — requirements coverage for pull requests
Codecov, but for your requirements. reqcov reads the requirements you already keep in your repository (Markdown, YAML or Doorstop), finds the tests and code that reference them, merges the JUnit results of your test run, and tells every pull request which requirements are uncovered, covered, verified or failing — then writes the traceability matrix an auditor asks for (IEC 62304, ISO 26262, EN 50128, DO-178C, IEC 61508, ECSS).
No server, no account, no new editor: a CLI + a GitHub Action.
## ❌ Requirements coverage: 83.3%
| Requirements | With test | Verified | Uncovered | Failing | Unknown ids | Orphan tests |
|---:|---:|---:|---:|---:|---:|---:|
| 8 | 5 | 5 | 1 | 0 | 0 | 1 |
- SRS: 75% of 4 testable requirements have a test
- SYS: 100% of 2 testable requirements have a test
### ❌ 1 error(s)
- `COVERAGE` test coverage of requirements 83.3% is below the required 100.0%
How it works
-
Requirements live in your repo, one id per requirement (
SYS-1,SRS-12,LLR-3…):## SRS-11 — Over-temperature cut-off The controller shall force the heater off when temperature ≥ 35 °C. Parent: SYS-2 Verification: testYAML lists and Doorstop items are also read.
-
Tests and code reference ids with a marker — any language, in a comment, a decorator, a macro:
@pytest.mark.req("SRS-11", "SYS-2") def test_overtemp_cutoff(): ...
/* @req LLR-12 */ void test_frame_bad_crc_is_rejected(void) { ... } /* @implements LLR-11, LLR-12 */ frame_status_t frame_validate(const uint8_t *frame, size_t len) { ... }
// @verifies SWR-2 TEST(RingBuffer, PushOnFullFails) { ... }
-
JUnit XML (pytest, Ceedling, GoogleTest, CTest, Jest, Maven…) turns covered into verified or failing.
-
Rules in
reqcov.ymldecide what fails the build: minimum coverage, unknown ids, orphan tests, mandatory parent links per level, mandatory@implementsper level.
Quick start
pip install reqcov
reqcov init # writes reqcov.yml — edit the globs
pytest --junitxml=reports/junit.xml
reqcov check # exit 1 on rule violations, writes reqcov-report/
open reqcov-report/index.html
reqcov-report/ contains index.html (interactive matrix), matrix.csv (auditor-friendly),
coverage.json (machine readable) and summary.md (the PR comment).
GitHub Action
name: requirements
on: [pull_request, push]
jobs:
reqcov:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- run: pip install -e . pytest && pytest --junitxml=reports/junit.xml
- uses: Antoine005/reqcov@v0
with:
junit: reports/junit.xml
The action posts (and keeps updating) one sticky comment on the pull request, writes the summary to the job page, emits annotations on the requirement lines that are uncovered or failing, and uploads the report directory as an artifact.
Configuration (reqcov.yml)
id_pattern: "[A-Z][A-Z0-9_]*-\\d+" # level = everything before the last dash
requirements: [docs/requirements/**/*.md]
sources: [src/**/*] # scanned for @implements markers
tests: [tests/**/*] # scanned for @req / @verifies markers
junit: [reports/*.xml]
markers: [req, requirement, implements, verifies, satisfies, trace]
rules:
min_test_coverage: 100 # % of testable requirements with ≥ 1 test
min_verified: null # % that must be verified (needs junit)
fail_on_unknown_ids: true
fail_on_orphan_tests: false
fail_on_failing_tests: true
require_parent_for: [SRS] # levels that must trace up
require_source_for: [] # levels that must have an @implements
allow_derived: true # missing parent = warning (false: error)
report:
out_dir: reqcov-report
formats: [html, csv, json, md]
title: "Software Requirements Traceability"
Requirement metadata
| Field | Markdown body line | YAML key | Values |
|---|---|---|---|
| parents | Parent: SYS-1, SYS-2 |
parent / parents / links |
ids |
| verification | Verification: test |
verification |
test (default), analysis, inspection, demonstration, none |
| status | Status: draft |
status (Doorstop: active: false → obsolete) |
free text; obsolete is ignored by rules |
| tags | Tags: safety, ui |
tags |
list |
Only requirements with verification: test count toward test coverage; the others are shown
as n/a in the matrix so the auditor still sees them.
Examples
examples/pytest-project— Python, SYS→SRS levels, one deliberate gap and one orphan test.examples/ceedling-unity— C, HLR→LLR,@implementsin sources, a failing Unity test propagating to two requirements.examples/googletest— C++, one-line requirements, GoogleTestSuite.Nameresults.
Status and roadmap
0.1 — CLI, Markdown/YAML/Doorstop input, marker scanning, JUnit merge, HTML/CSV/JSON/MD
reports, GitHub Action with sticky PR comment. Planned: coverage delta against the base
branch, StrictDoc and ReqIF input, Jira issue links, GitLab CI template, signed PDF export for
audit packages, hosted history and badges.
License
MIT.
Release files for reqcov 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| reqcov-0.1.0.tar.gz | 26.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reqcov-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.4 kB
Release files / reqcov-0.1.0.tar.gz
| Download URL | reqcov-0.1.0.tar.gz |
|---|---|
| Size | 26.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
81273b74596db34596536f74d5b07fccf9d560befb99ea4afd888ef1f57fea2f
|
|
BLAKE2b-256 checksum How to use checksums |
36f08a6b884cee092a979af4d39810990200d7fff5b85883fffb2e7514860b08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency logRelease files / reqcov-0.1.0-py3-none-any.whl
| Download URL | reqcov-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cd7b9c0d9f617f0b2025b0d0cd2b3f40f288816e2e7f8341ce79db607fd01000
|
|
BLAKE2b-256 checksum How to use checksums |
f8f080ac5733ed65dc45523511a2d3fae2e2ee89e3eb6677ebe7e07f448fbc2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency log