pytest-verifies 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytest_verifies-1.1.0/.github/workflows/ci.yml +99 -0
- pytest_verifies-1.1.0/.github/workflows/docs.yml +50 -0
- pytest_verifies-1.1.0/.github/workflows/release.yml +35 -0
- pytest_verifies-1.1.0/.gitignore +22 -0
- pytest_verifies-1.1.0/.pre-commit-config.yaml +27 -0
- pytest_verifies-1.1.0/.python-version +1 -0
- pytest_verifies-1.1.0/LICENSE +21 -0
- pytest_verifies-1.1.0/PKG-INFO +303 -0
- pytest_verifies-1.1.0/README.md +280 -0
- pytest_verifies-1.1.0/docs/compliance.md +25 -0
- pytest_verifies-1.1.0/docs/getting-started.md +71 -0
- pytest_verifies-1.1.0/docs/guide/assertions.md +149 -0
- pytest_verifies-1.1.0/docs/guide/baselines.md +71 -0
- pytest_verifies-1.1.0/docs/guide/consolidation.md +53 -0
- pytest_verifies-1.1.0/docs/guide/reports.md +36 -0
- pytest_verifies-1.1.0/docs/index.md +38 -0
- pytest_verifies-1.1.0/docs/reference.md +35 -0
- pytest_verifies-1.1.0/mkdocs.yml +72 -0
- pytest_verifies-1.1.0/pyproject.toml +67 -0
- pytest_verifies-1.1.0/src/pytest_verifies/__init__.py +13 -0
- pytest_verifies-1.1.0/src/pytest_verifies/baseline.py +156 -0
- pytest_verifies-1.1.0/src/pytest_verifies/cli.py +205 -0
- pytest_verifies-1.1.0/src/pytest_verifies/context.py +331 -0
- pytest_verifies-1.1.0/src/pytest_verifies/models.py +221 -0
- pytest_verifies-1.1.0/src/pytest_verifies/plugin.py +682 -0
- pytest_verifies-1.1.0/src/pytest_verifies/py.typed +0 -0
- pytest_verifies-1.1.0/src/pytest_verifies/reporters/__init__.py +84 -0
- pytest_verifies-1.1.0/src/pytest_verifies/reporters/csv_reporter.py +74 -0
- pytest_verifies-1.1.0/src/pytest_verifies/reporters/html_reporter.py +467 -0
- pytest_verifies-1.1.0/src/pytest_verifies/reporters/json_reporter.py +26 -0
- pytest_verifies-1.1.0/src/pytest_verifies/reporters/markdown_reporter.py +155 -0
- pytest_verifies-1.1.0/src/pytest_verifies/storage.py +312 -0
- pytest_verifies-1.1.0/tests/conftest.py +5 -0
- pytest_verifies-1.1.0/tests/test_api_and_hooks.py +621 -0
- pytest_verifies-1.1.0/tests/test_cli_and_reports.py +554 -0
- pytest_verifies-1.1.0/tests/test_filtering.py +250 -0
- pytest_verifies-1.1.0/tests/test_steps.py +180 -0
- pytest_verifies-1.1.0/tests/test_xdist.py +88 -0
- pytest_verifies-1.1.0/uv.lock +1520 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- 'feat/**'
|
|
8
|
+
pull_request:
|
|
9
|
+
branches:
|
|
10
|
+
- main
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
lint-and-typecheck:
|
|
18
|
+
name: Lint & Type Check
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- name: Check out repository
|
|
22
|
+
uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v5
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
|
|
29
|
+
- name: Synchronise environment
|
|
30
|
+
run: uv sync --all-groups
|
|
31
|
+
|
|
32
|
+
- name: Run Ruff linter
|
|
33
|
+
run: uv run ruff check .
|
|
34
|
+
|
|
35
|
+
- name: Check code formatting
|
|
36
|
+
run: uv run ruff format --check .
|
|
37
|
+
|
|
38
|
+
- name: Run Mypy type checker
|
|
39
|
+
run: uv run mypy src
|
|
40
|
+
|
|
41
|
+
test:
|
|
42
|
+
name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }})
|
|
43
|
+
runs-on: ${{ matrix.os }}
|
|
44
|
+
strategy:
|
|
45
|
+
fail-fast: false
|
|
46
|
+
matrix:
|
|
47
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
48
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
49
|
+
|
|
50
|
+
steps:
|
|
51
|
+
- name: Check out repository
|
|
52
|
+
uses: actions/checkout@v4
|
|
53
|
+
|
|
54
|
+
- name: Install uv
|
|
55
|
+
uses: astral-sh/setup-uv@v5
|
|
56
|
+
with:
|
|
57
|
+
enable-cache: true
|
|
58
|
+
|
|
59
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
60
|
+
run: uv python install ${{ matrix.python-version }}
|
|
61
|
+
|
|
62
|
+
- name: Synchronise environment
|
|
63
|
+
run: uv sync --all-groups --python ${{ matrix.python-version }}
|
|
64
|
+
|
|
65
|
+
- name: Run test suite with pytest
|
|
66
|
+
run: uv run pytest -v
|
|
67
|
+
|
|
68
|
+
docs-check:
|
|
69
|
+
name: Verify Documentation Build
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- name: Check out repository
|
|
73
|
+
uses: actions/checkout@v4
|
|
74
|
+
|
|
75
|
+
- name: Install uv
|
|
76
|
+
uses: astral-sh/setup-uv@v5
|
|
77
|
+
with:
|
|
78
|
+
enable-cache: true
|
|
79
|
+
|
|
80
|
+
- name: Synchronise documentation dependencies
|
|
81
|
+
run: uv sync --group docs
|
|
82
|
+
|
|
83
|
+
- name: Build documentation in strict mode
|
|
84
|
+
run: uv run --group docs mkdocs build --strict
|
|
85
|
+
|
|
86
|
+
package-check:
|
|
87
|
+
name: Verify Package Build
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
steps:
|
|
90
|
+
- name: Check out repository
|
|
91
|
+
uses: actions/checkout@v4
|
|
92
|
+
|
|
93
|
+
- name: Install uv
|
|
94
|
+
uses: astral-sh/setup-uv@v5
|
|
95
|
+
with:
|
|
96
|
+
enable-cache: true
|
|
97
|
+
|
|
98
|
+
- name: Build distribution artefacts
|
|
99
|
+
run: uv build
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: pages
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
deploy-docs:
|
|
20
|
+
name: Build & Deploy Documentation
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
environment:
|
|
23
|
+
name: github-pages
|
|
24
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
25
|
+
steps:
|
|
26
|
+
- name: Check out repository
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v5
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
|
|
34
|
+
- name: Synchronise documentation dependencies
|
|
35
|
+
run: uv sync --group docs
|
|
36
|
+
|
|
37
|
+
- name: Build documentation
|
|
38
|
+
run: uv run --group docs mkdocs build
|
|
39
|
+
|
|
40
|
+
- name: Set up GitHub Pages
|
|
41
|
+
uses: actions/configure-pages@v5
|
|
42
|
+
|
|
43
|
+
- name: Upload Pages artefact
|
|
44
|
+
uses: actions/upload-pages-artifact@v3
|
|
45
|
+
with:
|
|
46
|
+
path: site
|
|
47
|
+
|
|
48
|
+
- name: Deploy to GitHub Pages
|
|
49
|
+
id: deployment
|
|
50
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-and-publish:
|
|
13
|
+
name: Build & Publish to PyPI
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment:
|
|
16
|
+
name: pypi
|
|
17
|
+
url: https://pypi.org/p/pytest-verifies
|
|
18
|
+
permissions:
|
|
19
|
+
id-token: write # Mandatory for PyPA Trusted Publishing (OIDC)
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Check out repository
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v5
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: true
|
|
30
|
+
|
|
31
|
+
- name: Build distribution packages
|
|
32
|
+
run: uv build
|
|
33
|
+
|
|
34
|
+
- name: Publish package distribution to PyPI
|
|
35
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# Test and lint caches
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.ruff_cache/
|
|
16
|
+
.verifies/
|
|
17
|
+
*.jsonl
|
|
18
|
+
|
|
19
|
+
# Documentation & coverage builds
|
|
20
|
+
site/
|
|
21
|
+
.coverage
|
|
22
|
+
htmlcov/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# See https://pre-commit.com for more information
|
|
2
|
+
# Uses pre-commit-uv under the hood for accelerated environment creation via uv
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: v5.0.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
- id: check-yaml
|
|
10
|
+
- id: check-toml
|
|
11
|
+
- id: check-added-large-files
|
|
12
|
+
|
|
13
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
14
|
+
rev: v0.9.9
|
|
15
|
+
hooks:
|
|
16
|
+
- id: ruff
|
|
17
|
+
args: [--fix]
|
|
18
|
+
- id: ruff-format
|
|
19
|
+
|
|
20
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
21
|
+
rev: v1.15.0
|
|
22
|
+
hooks:
|
|
23
|
+
- id: mypy
|
|
24
|
+
additional_dependencies:
|
|
25
|
+
- pytest>=7.0
|
|
26
|
+
- pyyaml>=6.0
|
|
27
|
+
- types-PyYAML
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dale Collison
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pytest-verifies
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Enterprise requirements traceability plugin for pytest
|
|
5
|
+
Author-email: Dale Collison <dale.a.collison@gmail.com>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: Framework :: Pytest
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
19
|
+
Classifier: Topic :: Software Development :: Testing
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: pytest>=7.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# pytest-verifies
|
|
25
|
+
|
|
26
|
+
[](https://github.com/your-org/pytest-verifies)
|
|
27
|
+
[](https://www.python.org/)
|
|
28
|
+
[](LICENSE)
|
|
29
|
+
[](#standards-compliance)
|
|
30
|
+
|
|
31
|
+
**Enterprise Requirements Traceability Plugin for Pytest.**
|
|
32
|
+
|
|
33
|
+
`pytest-verifies` seamlessly links automated test suites to formal engineering requirements (such as ISO 26262, IEC 62304, DO-178C, and SOC2) and produces audit-ready Requirements Traceability Matrix (RTM) artefacts.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. Core Philosophy & Key Features
|
|
38
|
+
|
|
39
|
+
1. **Standard Pytest Assertions Only:**
|
|
40
|
+
No custom assertion wrappers. Use native Python `assert` statements inside `with verifies(...)` or on functions decorated with `@verifies(...)`. Pytest's AST assertion rewriting and rich diff diagnostics are 100% preserved.
|
|
41
|
+
2. **Unified API:**
|
|
42
|
+
A single callable, `verifies`, functions interchangeably as a function/class decorator, context manager, and parametrised mark (`pytest.param(..., marks=verifies(...))`).
|
|
43
|
+
3. **Soft Assertions & Objective Evidence:**
|
|
44
|
+
Support for non-fatal assertions (`soft=True` or `--verifies-soft`) enables tests to evaluate multiple requirements sequentially before reporting consolidated failures. Dynamically attach objective runtime evidence (`ctx.attach("telemetry", value)` or `ctx.record_evidence(dict)`).
|
|
45
|
+
4. **`pytest-xdist` Concurrency Safe:**
|
|
46
|
+
Workers never write directly to shared report files or depend on inter-process locks. Verification records are serialised onto `report.user_properties` and transmitted to the controller node.
|
|
47
|
+
5. **Multi-Run Shard Consolidation:**
|
|
48
|
+
Modelled after `coverage.py`. Distinct test invocations across disparate execution environments or CI stages (e.g. `unit`, `integration`, `system`) write atomic `.jsonl` shards. The standalone `pytest-verifies combine` CLI merges shards against baseline requirement manifests.
|
|
49
|
+
6. **Multi-Format Artefact Generation:**
|
|
50
|
+
Generates structured **JSON**, tabular **CSV**, GitHub/GitLab step summary **Markdown**, and interactive single-file **HTML5** reports with zero external runtime JavaScript or CSS dependencies.
|
|
51
|
+
7. **Strict Quality Gates:**
|
|
52
|
+
Enforce requirement coverage thresholds (`--verifies-fail-under`), disallow orphaned requirement IDs (`--verifies-disallow-orphans`), and fail pipelines when known defects or unverified requirements are detected.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 2. Installation
|
|
57
|
+
|
|
58
|
+
Install using `uv` (recommended):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv add pytest-verifies
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Or using standard Python package managers:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install pytest-verifies
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3. Quick Start & Python API
|
|
73
|
+
|
|
74
|
+
### 3.1 Decorator Usage
|
|
75
|
+
|
|
76
|
+
Decorate test functions or classes to associate them with one or more requirements:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from pytest_verifies import verifies
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@verifies("REQ-DOG-001", "REQ-DOG-002", description="Dogs must be friendly and able to bark")
|
|
83
|
+
def test_dog_attributes():
|
|
84
|
+
dog = {"name": "Buster", "species": "Canis familiaris", "barks": True}
|
|
85
|
+
assert dog["barks"] is True
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3.2 Single-Line Context Manager
|
|
89
|
+
|
|
90
|
+
Verify fine-grained inline statements while preserving full assertion diffs:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from pytest_verifies import verifies
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_cat_purring():
|
|
97
|
+
cat = {"name": "Whiskers", "purring": True}
|
|
98
|
+
with verifies("REQ-CAT-001"):
|
|
99
|
+
assert cat["purring"] is True
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3.3 Soft Assertions & Objective Evidence
|
|
103
|
+
|
|
104
|
+
Evaluate multiple requirements within a single test execution without early termination on the first failure:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from pytest_verifies import verifies
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_dog_health_and_energy():
|
|
111
|
+
dog = {"name": "Buster", "happy": True, "tail_wags_per_min": 120}
|
|
112
|
+
|
|
113
|
+
# Block 1: Soft assertion with static objective evidence
|
|
114
|
+
with verifies(
|
|
115
|
+
"REQ-DOG-002",
|
|
116
|
+
description="Dogs must wag their tails when happy",
|
|
117
|
+
soft=True,
|
|
118
|
+
evidence={"dog_name": dog["name"], "happy": dog["happy"]},
|
|
119
|
+
):
|
|
120
|
+
assert dog["happy"] is True
|
|
121
|
+
|
|
122
|
+
# Block 2: Execution continues even if Block 1 fails
|
|
123
|
+
with verifies("REQ-DOG-003", soft=True) as ctx:
|
|
124
|
+
ctx.attach("tail_wags_per_min", dog["tail_wags_per_min"])
|
|
125
|
+
ctx.record_evidence({"breed": "Golden Retriever"})
|
|
126
|
+
assert dog["tail_wags_per_min"] > 60
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 3.4 Parametrised Tests
|
|
130
|
+
|
|
131
|
+
Attach requirement tags to specific test parameters:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import pytest
|
|
135
|
+
from pytest_verifies import verifies
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@pytest.mark.parametrize(
|
|
139
|
+
"animal,sound",
|
|
140
|
+
[
|
|
141
|
+
pytest.param("dog", "woof", marks=verifies("REQ-DOG-001")),
|
|
142
|
+
pytest.param("cat", "meow", marks=verifies("REQ-CAT-001")),
|
|
143
|
+
pytest.param("puppy", "yip", marks=verifies("REQ-DOG-001")),
|
|
144
|
+
],
|
|
145
|
+
)
|
|
146
|
+
def test_pet_sounds(animal, sound):
|
|
147
|
+
pet_sounds = {"dog": "woof", "cat": "meow", "puppy": "yip"}
|
|
148
|
+
assert pet_sounds[animal] == sound
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 3.5 Test Procedure Steps & Action Steps
|
|
152
|
+
|
|
153
|
+
Test protocols often require tracking discrete step IDs (`STEP-01`, `1.1`), including **Action Steps** (preparing state) and **Verification Steps** (checking requirements):
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from pytest_verifies import step, verifies
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def test_puppy_training_routine():
|
|
160
|
+
# Action step: Prepare treat and call puppy
|
|
161
|
+
with step("STEP-01", description="Fill treat pouch and call puppy"):
|
|
162
|
+
puppy = {"name": "Buster", "tricks": []}
|
|
163
|
+
|
|
164
|
+
# Verification step: Directly validates REQ-DOG-004
|
|
165
|
+
with step("STEP-02", description="Verify puppy sits on command", verifies="REQ-DOG-004"):
|
|
166
|
+
puppy["tricks"].append("sit")
|
|
167
|
+
assert "sit" in puppy["tricks"]
|
|
168
|
+
|
|
169
|
+
# Verification step with verifies(..., step=...)
|
|
170
|
+
with verifies("REQ-DOG-002", step="STEP-03", description="Verify puppy wags tail after treat"):
|
|
171
|
+
tail_wagging = True
|
|
172
|
+
assert tail_wagging is True
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 4. Pytest Command-Line & Configuration Options
|
|
178
|
+
|
|
179
|
+
| Option | Ini Configuration | Description |
|
|
180
|
+
| :--- | :--- | :--- |
|
|
181
|
+
| `--req="PATTERN"` | — | Comma-separated requirement IDs or glob patterns to filter tests (e.g. `--req="REQ-DOG-*,REQ-CAT-001"`). |
|
|
182
|
+
| `--verifies-out=DIR` | `verifies_out = DIR` | Directory to output `.jsonl` execution shards. |
|
|
183
|
+
| `--verifies-stage=NAME` | `verifies_stage = NAME` | Stage label for execution shard (default: `"default"`). |
|
|
184
|
+
| `--verifies-baseline=PATH` | `verifies_baseline = PATH` | Path to baseline requirement manifest (`.json`, `.csv`, `.yaml`). |
|
|
185
|
+
| `--verifies-soft` | `verifies_soft = true` | Enable soft verification mode globally across all `verifies` blocks. |
|
|
186
|
+
| `--verifies-disallow-orphans`| — | Fail collection/session if tests reference IDs not present in baseline. |
|
|
187
|
+
| `--verifies-fail-under=NUM` | — | Fail session if verified requirement coverage % is below threshold (0–100). |
|
|
188
|
+
| `--verifies-json=PATH` | — | Direct output file for structured JSON RTM report. |
|
|
189
|
+
| `--verifies-csv=PATH` | — | Direct output file for tabular CSV RTM report. |
|
|
190
|
+
| `--verifies-md=PATH` | — | Direct output file for Markdown summary report. |
|
|
191
|
+
| `--verifies-html=PATH` | — | Direct output file for interactive single-file HTML5 report. |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 5. Baseline Requirement Manifests
|
|
196
|
+
|
|
197
|
+
Baseline manifests declare formal specifications against which automated tests are verified. Baseline requirements need only an `id` and a requirement statement `text` (or `description`).
|
|
198
|
+
|
|
199
|
+
### JSON Manifest (`requirements.json`)
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"requirements": [
|
|
203
|
+
{
|
|
204
|
+
"id": "REQ-DOG-001",
|
|
205
|
+
"text": "Dogs must be able to bark"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"id": "REQ-CAT-001",
|
|
209
|
+
"text": "Cats must be able to purr when content"
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### CSV Manifest (`requirements.csv`)
|
|
216
|
+
```csv
|
|
217
|
+
id,text
|
|
218
|
+
REQ-DOG-001,Dogs must be able to bark
|
|
219
|
+
REQ-CAT-001,Cats must be able to purr when content
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### YAML Manifest (`requirements.yaml`)
|
|
223
|
+
```yaml
|
|
224
|
+
requirements:
|
|
225
|
+
- id: REQ-DOG-001
|
|
226
|
+
text: Dogs must be able to bark
|
|
227
|
+
- id: REQ-CAT-001
|
|
228
|
+
text: Cats must be able to purr when content
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 6. Multi-Run Shard Consolidation Workflow
|
|
234
|
+
|
|
235
|
+
In distributed CI pipelines, different test tiers (unit, integration, end-to-end) run in isolated containers. `pytest-verifies` enables merging these shards into a single consolidated matrix:
|
|
236
|
+
|
|
237
|
+
### Step 1: Run Stage Test Suites
|
|
238
|
+
```bash
|
|
239
|
+
# Unit test tier
|
|
240
|
+
uv run pytest tests/unit --verifies-out=.verifies --verifies-stage=unit
|
|
241
|
+
|
|
242
|
+
# Integration test tier
|
|
243
|
+
uv run pytest tests/integration --verifies-out=.verifies --verifies-stage=integration
|
|
244
|
+
|
|
245
|
+
# End-to-end / System test tier
|
|
246
|
+
uv run pytest tests/system --verifies-out=.verifies --verifies-stage=system
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Step 2: Combine Shards via CLI
|
|
250
|
+
```bash
|
|
251
|
+
uv run pytest-verifies combine .verifies/ \
|
|
252
|
+
--baseline requirements.json \
|
|
253
|
+
--disallow-orphans \
|
|
254
|
+
--fail-under 100.0 \
|
|
255
|
+
--json rtm.json \
|
|
256
|
+
--csv rtm.csv \
|
|
257
|
+
--md rtm.md \
|
|
258
|
+
--html rtm.html
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Quality Gate Exit Codes
|
|
262
|
+
- **`0`**: Success. All quality gates met (100% of tested requirements verified, coverage threshold met, no orphaned IDs).
|
|
263
|
+
- **`1`**: Quality gate failure. One or more requirements failed, orphaned IDs were detected, or verified requirement coverage is below `--fail-under`.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 7. Reporting Artefacts
|
|
268
|
+
|
|
269
|
+
### Interactive HTML5 Report
|
|
270
|
+
Self-contained, responsive, single-file HTML5 document with zero external network dependencies:
|
|
271
|
+
- **Metric Cards:** Total Requirements, Verified %, Failed %, Unverified %, Orphan Count.
|
|
272
|
+
- **Dynamic Filtering:** Instant filtering by status (`All`, `Verified`, `Failed`, `Unverified`, `Orphans`).
|
|
273
|
+
- **Live Search:** Fast search by Requirement ID, title, test nodeid, or file location.
|
|
274
|
+
- **Diagnostic Expansion:** Interactive `<details>` sections displaying execution trace, attached objective evidence, and failure tracebacks.
|
|
275
|
+
|
|
276
|
+
### GitHub / GitLab Markdown Summary
|
|
277
|
+
Designed directly for `$GITHUB_STEP_SUMMARY` and merge request comments:
|
|
278
|
+
- Summary Scorecard Table with clean status indicators (`VERIFIED`, `FAILED`, `PARTIAL`, `UNVERIFIED`, `[ORPHAN]`).
|
|
279
|
+
- Requirements Traceability Table detailing stage coverage and verification tests.
|
|
280
|
+
- Collapsible diagnostics with assertion tracebacks and formatted JSON evidence.
|
|
281
|
+
|
|
282
|
+
### Tabular CSV Export
|
|
283
|
+
Standardised format for enterprise PLM / ALM tools (e.g. Jira, Jama, Polarion):
|
|
284
|
+
```csv
|
|
285
|
+
req_id,title,status,in_baseline,stages,verified_by_tests,evidence,failure_messages
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 8. Standards Compliance
|
|
291
|
+
|
|
292
|
+
| Standard | Applicable Clauses | How `pytest-verifies` Supports Compliance |
|
|
293
|
+
| :--- | :--- | :--- |
|
|
294
|
+
| **ISO 26262** | Part 6, Section 9 & 10 | Provides bidirectional requirements-to-test traceability and verification evidence for ASIL A–D. |
|
|
295
|
+
| **IEC 62304** | Section 5.7 & 5.8 | Establishes automated software verification records and RTM reports for Class A–C medical software. |
|
|
296
|
+
| **DO-178C** | Section 6.4.4 | Demonstrates verification of software requirements and records objective test execution results. |
|
|
297
|
+
| **SOC2 / ISO 27001** | CC7.1, CC7.4 | Auditable proof that automated security controls and regression tests verify baseline control specifications. |
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## 9. Licence
|
|
302
|
+
|
|
303
|
+
Distributed under the terms of the **MIT** licence.
|