Skip to main content

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

  1. 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: test
    

    YAML lists and Doorstop items are also read.

  2. 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) { ... }
    
  3. JUnit XML (pytest, Ceedling, GoogleTest, CTest, Jest, Maven…) turns covered into verified or failing.

  4. Rules in reqcov.yml decide what fails the build: minimum coverage, unknown ids, orphan tests, mandatory parent links per level, mandatory @implements per 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

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)

Source distribution for reqcov 0.1.0
File Size Uploaded
reqcov-0.1.0.tar.gz 26.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for reqcov 0.1.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page