Pytest plugin and protocol for pausing live test execution and resuming in-process
Project description
pytest-live-pause
pytest-live-pause is intended to be a standalone pytest plugin and runtime protocol for pausing a live test process, inspecting state before teardown, and resuming the same process through a structured control channel.
The repository is currently in bootstrap stage. The design target is:
- a transport-neutral pause runtime
- a thin pytest plugin adapter
- structured stdout and JSONL events
- packaged CLI commands for monitoring and resuming paused runs
- a compatibility layer for existing QAMule-style workflows
The current design scope lives in CURRENT_SCOPE.md.
Current Status
The first working slice is --pause-on-failure using a file-backed control channel.
Checkpoint pauses are also supported through pytest_live_pause.checkpoint(...).
The plugin also auto-registers live_pause and pause_run_id fixtures for direct injection into test function arguments.
When a test fails in the call phase and --pause-on-failure is enabled, the plugin:
- writes a pause request JSON file
- waits for an external resume command file or timeout
- resumes the same pytest process before teardown starts
- appends any externally supplied failure reason to the pytest report
Tests can also pause explicitly:
from pytest_live_pause import checkpoint
def test_example():
decision = checkpoint(task="Approve the external step", timeout=300)
if decision.result is False:
raise AssertionError(decision.reason or "checkpoint failed")
Or through the auto-registered fixture:
```python
def test_example(live_pause, pause_run_id):
assert live_pause.run_id == pause_run_id
decision = live_pause.checkpoint(task="Approve the external step", timeout=300)
assert decision.result is True
```
Checkpoint resumes use --result and --reason:
pytest-live-pause resume <pause_id> --result true --reason "approved"
Checkpoint behavior can also be mocked during pytest startup:
pytest --pause-checkpoint-mock false
Usage
Run pytest with pause-on-failure enabled:
pytest --pause-on-failure --pause-timeout 300
By default, pause state is written under /tmp/pytest-live-pause.
You can still override it explicitly:
pytest --pause-on-failure --pause-dir /some/other/path --pause-timeout 300
When a test fails, a pause file appears under the run directory:
/tmp/pytest-live-pause/
runs/<run_id>/
events.jsonl
run.json
pauses/<pause_id>.json
commands/
Resume the paused failure by pointing the CLI at the pause file:
pytest-live-pause resume \
/tmp/pytest-live-pause/runs/<run_id>/pauses/<pause_id>.json \
--failure-reason "manually confirmed"
You can also resume directly by pause_id, which is more convenient when multiple pytest processes share the same pause directory:
pytest-live-pause resume <pause_id> --failure-reason "manually confirmed"
If you are using a non-default pause directory, pass it explicitly:
pytest-live-pause resume <pause_id> --pause-dir /some/other/path --failure-reason "manually confirmed"
For failure pauses, --failure-reason appends an extra explanation to the pytest failure report. Non-failure pauses must not receive --failure-reason; the CLI will reject that combination.
For checkpoint pauses, use --result true|false|none and optional --reason.
For mocked checkpoint pauses, reason is fixed to Mock.
The CLI writes the matching command file into commands/. The pytest process polls for that command and then continues into teardown.
When multiple pytest processes share the same pause directory, each process gets its own runs/<run_id>/ directory. run.json and each pause file also record pid, hostname, cwd, and optional worker_id metadata.
You can inspect currently pending pauses across all runs with:
pytest-live-pause ls
You can also watch for newly paused tests in real time:
pytest-live-pause watch --run-id <run_id>
watch requires a specific pytest run_id:
pytest-live-pause watch --run-id <run_id>
For bounded monitoring, pass a timeout:
pytest-live-pause watch --run-id <run_id> --timeout 30
watch waits until the latest matching pending pause appears, prints the pause details, and then exits.
If the monitored pytest process exits while watch is still polling, watch now stops immediately and reports that the run is no longer active.
By default, ls only shows currently resumable pending pauses. To include stale, resumed, and timed_out entries, use:
pytest-live-pause ls -a
If a pytest process is killed while paused, its pause file remains on disk. The CLI treats that as stale when the recorded pid is no longer alive on the current host. ls -a will show the stale state, and resume will refuse to write a command for it.
If no command arrives before --pause-timeout, the test resumes automatically without adding an external failure reason.
When pytest starts, it prints the current run_id, so you can monitor that specific pytest process with pytest-live-pause watch --run-id <run_id>.
File Protocol
pauses/<pause_id>.json currently contains:
{
"pause_id": "...",
"run_id": "...",
"nodeid": "tests/test_sample.py::test_failure",
"timeout": 300.0,
"original_failure": "AssertionError: boom",
"status": "pending",
"created_at": 1710000000.0,
"pid": 12345,
"hostname": "host.local",
"cwd": "/repo"
}
commands/<pause_id>.resume.json currently contains:
{
"failure_reason": "manually confirmed"
}
Or for a checkpoint pause:
{
"result": true,
"reason": "approved"
}
This file transport is only the first implementation. The runtime can be split from the transport later if you want to add sockets or HTTP.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_live_pause-0.1.1.tar.gz.
File metadata
- Download URL: pytest_live_pause-0.1.1.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2ab44622507c67cd35daa7beaaeba56217340cbc284f6b0cb886736240d3fa0
|
|
| MD5 |
fb7f86d625b162a719c54a676b0517f9
|
|
| BLAKE2b-256 |
c80578b994b68c0356539f89f1d2805dad7199779f76535bcab8b9f76029327a
|
File details
Details for the file pytest_live_pause-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pytest_live_pause-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fa4d5ee84864b75a16a3e530b8ee184cea466ce83989d3c86f8163e2d94fefd
|
|
| MD5 |
0e866d70c7cfbd9da43a01211a03b0a2
|
|
| BLAKE2b-256 |
a327e0354f06846dbb2d0c78846002053b11c3a8cbb45f10abaa62462f70c60e
|