Skip to main content

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=[...] in story.init(...)
  • Step timing: start_timer / end_timer
  • Attachments: attach(...)
  • OTel spans + trace links: attach_spans(...), trace_url_template in story.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 it
  • incompleteSourceFiles — 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 before story.init
  • runScope — "filtered" for -k, -m, --deselect, --last-failed, a file.py::test node id, or a run that ended early (-x, --maxfail, Ctrl-C, an internal or usage error); otherwise "full"
  • gitSha and packageVersion — 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)

Source distribution for executable-stories-pytest 0.1.1
File Size Uploaded
executable_stories_pytest-0.1.1.tar.gz 33.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for executable-stories-pytest 0.1.1
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

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