Skip to main content

pytest-xspec

PyPI version Python versions Tests Code coverage

Executable specifications with pytest.

Link specifications to your existing pytest tests, organize your test suite your way, and see which specifications your test suite verifies. Detect missing tests and enforce verification in CI.

Usage

Install pytest-xspec into your pytest environment. The plugin is discovered automatically. Python 3.10+ and pytest 8+ are supported.

pip install pytest-xspec

Declare specifications

Declare specification IDs under requirements in pyproject.toml.

[tool.xspec]
requirements = ["REQ-001", "REQ-002"]

Alternatively, use one ID per line in pytest.ini.

[pytest]
xspec =
    REQ-001
    REQ-002

Declare specifications in one of these files. Using both is an error, and other files do not supply specifications. IDs are opaque strings. Duplicates and marked IDs that have not been declared are rejected. No inventory, or an empty inventory, means zero specifications.

Mark tests

Associate tests with specifications, using one marker per specification.

import pytest


@pytest.mark.xspec("REQ-001")
@pytest.mark.xspec("REQ-002")
def test_shared_behavior():
    assert 1 + 1 == 2

Run pytest

Plain pytest checks specification configuration and markers without printing a specification report. Add --xspec-report to see the report, or --xspec-strict to also fail the run when a specification is unverified.

pytest --xspec-report             # Print the verification report
pytest --xspec-json=report.json   # Export statuses and individual test outcomes
pytest --xspec-strict             # Report and fail on unverified specifications
pytest -m xspec --xspec-strict    # Run only marked specification tests

The report is green when all specifications are verified and red when verification fails. The first report shows the example above; the second shows a specification without tests.

Terminal reports showing verified specifications in green and a missing specification in red.

Read specification statuses

Reports label specifications as requirements.

A specification is verified when every test marked with its ID passes. One passing test is not enough if another test for the same specification fails or skips.

When those tests have different results, the report uses the first matching status in this table, reading from top to bottom.

Status Meaning
ERROR A test's setup or cleanup failed.
FAILED A test failed.
XPASSED A test marked as an expected failure passed instead.
XFAILED A test failed as expected.
SKIPPED A test was skipped or never ran.
DESELECTED A test was excluded by a filter such as -k or -m.
PASSED Every test for the specification passed.

For example, if one test passes and another skips, the specification is SKIPPED and remains unverified. If one test fails and another skips, it is FAILED.

Missing and unfinished tests

Pytest first finds tests, then runs them. If it finds no marked tests for a declared specification, that specification is MISSING. Tests that were found but never ran are SKIPPED, including runs that only find tests or stop early. If pytest encounters an error while finding tests, such as a broken import, the verification check cannot succeed.

Tests without markers

Tests without a specification marker do not change specification statuses. They can still make pytest fail. In the duck example, the specification passes, but the unmarked cheese test fails the pytest run.

Check coverage

Coverage is the percentage of declared specifications that are verified. With no declared specifications and no errors while finding tests, the verification check succeeds and coverage is 0.0%.

Errors while finding tests make verification fail, even at 100% coverage. The report follows pytest's color settings, so --color=no disables color.

For a complete report, let pytest find the whole test suite. With -k or -m, the plugin still knows about the tests excluded by the filter and reports marked ones as DESELECTED. If you run only one folder, it cannot see tests in other folders.

Runnable examples

Start with the pizza, then try the other examples to see what makes a specification pass or remain unverified.

Run the commands below from the repository root. Dependencies are installed automatically.

Example With --xspec-strict Exit code
Quickstart - Two slices of pizza PASSED, 100% coverage 0
Missing specification - A lost sock MISSING, 50% coverage 1
Partial verification - Cat skips a meeting SKIPPED, 0% coverage 1
Acceptance only - Duck versus cheese PASSED with -m xspec 0

Run an example

Run the Quickstart example, then replace quickstart with another example folder.

uv run --locked pytest examples/quickstart --xspec-strict

For acceptance_only, add -m xspec to run only the marked test. Without that filter, the unmarked test makes pytest fail.

Inspect the JSON report

Export the example results to see the specification status and individual test outcomes.

uv run --locked pytest examples/quickstart --xspec-json=examples/quickstart/report.json

Open examples/quickstart/report.json after running the command.

Verify all examples

Check that every example behaves as described.

uv run --locked pytest examples/test_examples.py -n 0

All five checks should pass, including checks for the examples that deliberately fail. The examples are also verified in CI.

Contributing

See CONTRIBUTING.md for setup, tests and pull requests.

Metadata

Release files for pytest-xspec 0.5.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 pytest-xspec 0.5.0
File Size Uploaded Provenance
pytest_xspec-0.5.0.tar.gz 128.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-xspec 0.5.0
File Interpreter ABI Platform
pytest_xspec-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 138.1 kB

Release files / pytest_xspec-0.5.0.tar.gz

Download URL pytest_xspec-0.5.0.tar.gz
Size 128.5 kB
Tags Source
SHA-256 checksum
How to use checksums
0f01b1a4a7df09da47673307ef36495625c9dc87c1e70214b5f3b1822e1351da
BLAKE2b-256 checksum
How to use checksums
44bc4eaccdf82df8ca61975b0ad7758f229c858391cfadacd73a11c82730edd5
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 Oct 15, 2026.

Transparency log

Release files / pytest_xspec-0.5.0-py3-none-any.whl

Download URL pytest_xspec-0.5.0-py3-none-any.whl
Size 9.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
997597c6e0194947d88babb6fe856a4e56ada6c97ff50010ca9734e8ebd3ae3e
BLAKE2b-256 checksum
How to use checksums
856c16fbb13e494fdb348498b16e5d25a0f5bc568968f8a69deeb506e8c7113a
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 Oct 15, 2026.

Transparency log

Security for pytest-xspec 0.5.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pytest_xspec-0.5.0.tar.gz

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 Oct 15, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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