pytest-given
A pytest plugin that turns Given/When/Then annotated tests into interactive HTML reports.
Given your pytest tests,
when you narrate them with given / when / then,
then documentation and behavior fuse into one report.
What people and agents read is what the code does.
Inspired by JGiven (Java).
Documentation: https://nwilbert.github.io/pytest-given/latest/
Live examples:
- Coffeeshop: a tour of the core features.
- Hotel booking: a glossary and domain stories, with story coverage.
- File glossary: the same, with the glossary kept in a Markdown file.
- Self-report: pytest-given's own test suite.
Quick start
pip install pytest-given
Requires Python ≥ 3.14 (t-strings — PEP 750 — are part of the step-text API) and pytest ≥ 9.0.
If AI agents work in your repo, also install the bundled agent skills — with pytest-given's own command, or with library-skills alongside the skills of your other dependencies:
pytest-given skills install
# or
uvx library-skills install --claude
Then narrate a test:
import pytest
from pytest_given import attach, given, scenario, then, when
@pytest.fixture
@given('a coffee machine with 10 coffees')
def machine():
return {'coffees': 10, 'price': 2}
@scenario('Buying a coffee takes one from the machine', tags=['checkout'])
def test_buy_coffee(machine):
with when('I buy a coffee'):
machine['coffees'] -= 1
with then('the machine has 9 coffees left'):
assert machine['coffees'] == 9
attach('Machine state', machine)
Run it:
pytest --given-html
This produces given-report/report.html — one file you can open directly in a browser.
The Coffeeshop example's report shows this same scenario:
✅ Buying a coffee takes one from the machine
Why pytest-given?
Classical BDD tools (Cucumber, behave, pytest-bdd) center on Gherkin, a natural-language DSL: stakeholders write the tests, and engineers maintain the glue code behind each step. The BDD page writes the quick start's scenario that way, for comparison.
pytest-given works the other way round: engineers or their agents write normal tests, and pytest-given turns them into readable documentation. Stakeholders and domain experts can follow the HTML report without ever opening the test suite. Engineers get a view of the system's behavior that is easier to scan than test code, browsable by tag, glossary term, or module. The approach is the one JGiven pioneered for Java, brought to pytest.
- Plain Python: no Gherkin, no
.featurefiles, no parser. - Tests stay first-class pytest tests, and the report is a by-product.
- Self-contained HTML: open it locally or attach it to a CI run, with no server and no external assets.
Written by agents, reviewed by people
Most tests are no longer written by hand. A person describes the behavior they want, in a prompt or a spec, and an AI agent writes the tests along with the code. People review the narrated report first, and the test code behind it where it matters. The diagram shows this loop, and Working with AI agents explains how to set it up.
Glossary and Domain Storytelling
pytest-given goes beyond JGiven by tying tests to the domain itself. A glossary defines the terms your team uses, and the report highlights them wherever a test mentions them. Domain Storytelling adds the big picture: stories of how the domain works, with the report showing which scenarios cover each sentence of a story.
Documents that stay true
A design spec or a README can cite scenarios, tags and stories as links into the report, each led by its current status. pytest-given citations update keeps the citations in line with the latest run. pytest-given citations check in CI fails when a cited scenario stops passing or disappears, so the document can't quietly claim what the code no longer does.
Features
- Step context managers:
with given(...),when(...),then(...)blocks in plain pytest tests, nesting within a phase. - Narrated fixtures:
@givenon a fixture, orAnnotated[..., given(...)]on a parameter, records setup as a step. - Parametrized scenarios: one narrated tree plus a parameter table per case, or one scenario per case on request.
- Glossary: your domain's terms, declared in code or loaded from a
GLOSSARY.md, rendered as highlighted term refs in the narration. - Domain Storytelling: Domain Stories as sequences of sentences, and per-sentence coverage in the report.
- Reports: a self-contained HTML report to browse and share, and a Markdown report for diffs, reviews and agents.
- Narration lint: structural checks that a step's text is honest about its body: empty steps, a
thenthat checks nothing, a missing phase. - Citations: links from Markdown documents to scenarios, tags and stories, led by their status and checked against the latest run.
- Agent skills: bundled Agent Skills for authoring, navigating and reviewing narrated tests, installable with one command.
The full reference — pytest options, source links, the standalone CLI — is on the documentation site.
License
MIT. The bundled Alpine.js runtime is also MIT, with its notice in THIRD-PARTY-LICENSES.
Metadata
Release files for pytest-given 0.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pytest_given-0.5.1.tar.gz | 637.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_given-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.0 MB
Release files / pytest_given-0.5.1.tar.gz
| Download URL | pytest_given-0.5.1.tar.gz |
|---|---|
| Size | 637.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e0d698fef3d8651b41021e9b00b183956bb16d131f05ee17df56f5c0b888a88f
|
|
BLAKE2b-256 checksum How to use checksums |
cf6ed89774fa7ad05b085d6528f3e9ff1a8faa4033fa75012421f693a42c7df6
|
| 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 24, 2026.
Transparency logRelease files / pytest_given-0.5.1-py3-none-any.whl
| Download URL | pytest_given-0.5.1-py3-none-any.whl |
|---|---|
| Size | 370.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
338327e4184395422290da59434d4d2644762bef73542ceba310b9e5188be29d
|
|
BLAKE2b-256 checksum How to use checksums |
b4b45c83c104bf5a79d70b7ab56d8dda26501165f2e2441e855063d63228f38f
|
| 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 24, 2026.
Transparency logSecurity for pytest-given 0.5.1
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.
Attestation for pytest_given-0.5.1.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 24, 2026.
Transparency logA 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.