Skip to main content

pytest-deck

CI

An interactive browser dashboard for pytest. Collect your suite as a foldable tree, pick what to run with checkboxes or marker chips, and watch results stream in test by test, with tracebacks and captured output one click away.

Its defining promise: a deck run matches a real command-line pytest run. Every collect, reload, and run is a fresh python -m pytest subprocess, never in-process. What you see in the browser is what your terminal would say, and a crashing or hanging test can't take the dashboard down with it.

Beta. Collect, select, run with live streaming, reload with diff, plugin switches, coverage down to a source gutter, benchmark timings, and per-test attachments all work. See the changelog and the docs for the full picture.

Install

pip install pytest-deck

Quick start

pytest-deck is a pytest plugin. Launch the dashboard with --deck:

pytest --deck                 # dashboard for the current project (rootdir)
pytest --deck path/to/tests   # dashboard for a specific path

Nothing runs in the terminal. The deck prints its URL (http://127.0.0.1:8765/ by default); open it in your browser and your suite is there as a foldable tree.

Without --deck the plugin is inert: your normal pytest runs are completely unaffected.

To see everything at once, point the deck at this repo's examples/ suite. Install the plugins you want to try and run pytest --deck examples/.

For the full tour, start with the quickstart.

Features

The live basics

  • A foldable file → class → test → parametrized-variant tree with rollup counts on every group.
  • Select with checkboxes, marker chips that bulk-select every matching test, and -k / -m expression fields.
  • Hit ▶ Run and PASS / FAIL / ERROR / SKIP stream in live as each test finishes, tracebacks in pytest's own colors, captured output alongside.
  • Re-run failed: one click re-runs everything currently failed or errored, regardless of the selection.
  • ↻ Collect to re-collect after an edit: added, removed, and changed tests are flagged, and selection plus results are preserved for tests that still exist.

Plugins

Installed plugins appear as switches in the sidebar, each with a typed config form, so you never have to hunt through a plugin's flags. Switches ship ready-made for:

  • pytest-cov
  • pytest-benchmark
  • pytest-mpl
  • pytest-metadata
  • pytest-mock
  • pytest-asyncio
  • pytest-django

For any other plugin, a one-file TOML description (a manifest) in .pytest-deck/plugins/ adds a switch of your own.

Your ini addopts aren't lost either. Each token either prefills a switch's config form, follows its plugin's switch automatically, or shows up as a clickable suggestion chip. Nothing is dropped silently.

Plugins guide · Writing your own manifest

Standalone server

The dashboard also runs without the pytest CLI:

pytest-deck path/to/tests            # console script
python -m pytest_deck.server path/to/tests

One difference from pytest --deck path/to/tests: the standalone command roots the project at the path you give, with no walk up to find the root.

Options: --host (default 127.0.0.1), --port (must be free; default: first free port from 8765, up to 8785, announcing any fallback), and --open (open a browser tab on launch; off by default). Through pytest, --deck-port is the same as --port.

How it works

Every collect and run is a fresh pytest subprocess. A small plugin injected into those subprocesses emits structured JSON on a dedicated file descriptor, a private channel that keeps machine-readable results separate from pytest's captured output. A FastAPI backend streams those events to the browser over Server-Sent Events. The deep dive lives in the docs: How It Works.

Documentation

Full documentation is at pytest-deck.readthedocs.io:

Limitations

  • pytest-xdist is not supported. The deck reads each run's results over a dedicated pipe, and xdist's worker subprocesses don't inherit that pipe, so results would never reach the dashboard. The deck therefore forces -p no:xdist for its own runs: if xdist is installed in your project it stays disabled here, and runs are serial.
  • Localhost only. The server binds to 127.0.0.1 with no auth, and it executes your test code. Don't expose it on an untrusted network.

Development

Requires Python 3.11+ and Node 24 LTS (for the frontend build).

# backend
pip install -e ".[test]"
pytest                       # the full suite

# frontend (Svelte 5 + Vite); builds into pytest_deck/static/
cd frontend
npm install
npm run build

Run the full matrix (Python 3.11 to 3.14 × pytest 8/9, plus the frontend build) with tox. The development guide has the details.

pytest-deck is written with AI assistance. The design decisions, the reviews, and the bugs are mine. AI-assisted contributions are welcome here, held to the same bar.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_deck-0.1.0.tar.gz (479.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_deck-0.1.0-py3-none-any.whl (117.6 kB view details)

Uploaded Python 3

File details

Details for the file pytest_deck-0.1.0.tar.gz.

File metadata

  • Download URL: pytest_deck-0.1.0.tar.gz
  • Upload date:
  • Size: 479.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pytest_deck-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a789bbdfeb1f2d70613adf13f2f54f72020dd91832f7e079bcfb128a482cf7b3
MD5 c9f7cb78de45db2a79081cb0b49f320d
BLAKE2b-256 d431a3438a21fb0e2de2ca919b2cc4363fee6f3adf2ab5f0a9ea0fc2c4ad8a81

See more details on using hashes here.

File details

Details for the file pytest_deck-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_deck-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 117.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pytest_deck-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7742ee4d581e7fc033ac1e54676f9350a37373309ff6bf6132d098b7348865c0
MD5 680fdb18721118197473730eb3965744
BLAKE2b-256 9b2d661dc66e3530e7ec7b902b96d03fdecbdbcfb0e44c219aba43cd5cd5992d

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 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