executable-stories-pytest
pytest plugin for executable-stories.
Adds BDD-style story helpers and emits raw story run JSON so pytest tests can be rendered into executable documentation.
Install
pip install executable-stories-pytest
The PyPI distribution name is executable-stories-pytest, but the import name is executable_stories:
from executable_stories import story
Usage
from executable_stories import story
def test_login_success():
story.init("User logs in", tags=["auth", "smoke"])
story.given("a registered user")
story.when("they submit valid credentials")
story.then("they see the dashboard")
Features
- BDD steps:
given,when,then,and_,but - Aliases:
arrange,act,assert_,setup,context,execute,action,verify - Rich docs:
note,tag,kv,json,code,table,link,section,mermaid,screenshot,video,html,state,custom story.state(value, label=None)— JSON-serializable snapshot of "what the world looks like" at this step (a storyboard frame); consecutive same-label states are diffed at render time- Feature declarations:
story.feature(...)at module level heads every scenario in the file - Planned scenarios:
story.planned("…")records behaviour that is specified but not built - Source coverage links:
covers=[...]instory.init(...) - Step timing:
start_timer/end_timer - Attachments:
attach(...) - OTel spans + trace links:
attach_spans(...),trace_url_templateinstory.init(...),OTEL_TRACE_URL_TEMPLATE
Output
The plugin writes .executable-stories/raw-run.json under pytest's root directory when the
session finishes. Set EXECUTABLE_STORIES_OUTPUT to move it: a relative path is resolved
against the project root, an absolute one is used as given. The file is renamed into place,
so a reader never sees a half-written run.
Formatting the raw run updates one canonical report per source file under reports/by-file/.
Each run says what it reached so those reports stay honest as tests come and go:
coveredSourceFiles— every file the run executed a test in, whether or not it produced a story, so deleting a file's last scenario retires itincompleteSourceFiles— files the run cannot speak for: a skipped test, a broken fixture or teardown, a module that failed to import, or a test that failed beforestory.initrunScope—"filtered"for-k,-m,--deselect,--last-failed, afile.py::testnode id, or a run that ended early (-x,--maxfail, Ctrl-C, an internal or usage error); otherwise"full"gitShaandpackageVersion— which commit the run describes, and what produced it
Source paths are relative to the project root, so a report keeps its identity across machines and CI.
pytest exposes no assertion counter. Use story.expect("claim", callable) to declare
assertion evidence. A plain story.then() followed by Python assert remains unobserved,
not zero.
Pass that file to the executable-stories CLI (from the executable-stories-formatters package) to render reports:
npx --package executable-stories-formatters executable-stories format .executable-stories/raw-run.json --format html
# The path is optional — `format` defaults to .executable-stories/raw-run.json
npx --package executable-stories-formatters executable-stories format --format html
# Diagnose the run JSON if a report won't generate (schema drift, empty run)
npx --package executable-stories-formatters executable-stories doctor
Supported formats include html, markdown, junit, and the Cucumber outputs. Use --output-dir to choose where reports are written.
Verify
From repo root:
pnpm run verify:pytest
Metadata
Release files for executable-stories-pytest 0.1.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 | |
|---|---|---|---|
| executable_stories_pytest-0.1.1.tar.gz | 33.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| executable_stories_pytest-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.8 kB
Release files / executable_stories_pytest-0.1.1.tar.gz
| Download URL | executable_stories_pytest-0.1.1.tar.gz |
|---|---|
| Size | 33.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6ddeda5b03c1843616afc1f3c736e140c47834f284294e069b7aa6f1026c2edf
|
|
BLAKE2b-256 checksum How to use checksums |
dbea9bfd4825bdcefef3192a43417bf7b22c15bf397141d746a4d1fe38599b44
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / executable_stories_pytest-0.1.1-py3-none-any.whl
| Download URL | executable_stories_pytest-0.1.1-py3-none-any.whl |
|---|---|
| Size | 23.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19add0e2825fe49ee2a5576d4a5e157a5918de2b00ffea50478bafca324ef4a2
|
|
BLAKE2b-256 checksum How to use checksums |
ee2d0e79400d4b73c39a9db7b243f42aa051c5d1c2782551c2294364fee0c965
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|