Skip to main content

pytest-replay

http://img.shields.io/pypi/v/pytest-replay.svg https://anaconda.org/conda-forge/pytest-replay/badges/version.svg https://github.com/ESSS/pytest-replay/workflows/test/badge.svg https://img.shields.io/pypi/pyversions/pytest-replay.svg https://img.shields.io/badge/code%20style-black-000000.svg

Saves previous test runs and allow re-execute previous pytest runs to reproduce crashes or flaky tests


This pytest plugin was generated with Cookiecutter along with @hackebrot’s Cookiecutter-pytest-plugin template.

Features

This plugin helps to reproduce random or flaky behavior when running tests with xdist. pytest-xdist executes tests in a non-predictable order, making it hard to reproduce a behavior seen in CI locally because there’s no convenient way to track which test executed in which worker.

This plugin records the executed node ids by each worker in the directory given by --replay-record-dir=<dir> flag, and a --replay=<file> can be used to re-run the tests from a previous run. For example:

$ pytest -n auto --replay-record-dir=build/tests/replay

This will generate files with each line being a json with the following content: node identification, start time, end time and outcome. It is interesting to note that usually the node id is repeated twice, that is necessary in case of a test suddenly crashes we will still have the record of that test started. After the test finishes, pytest-replay will add another json line with the complete information. That is also useful to analyze concurrent tests which might have some kind of race condition and interfere in each other.

For example worker gw1 will generate a file .pytest-replay-gw1.txt with contents like this:

{"nodeid": "test_foo.py::test[1]", "start": 0.000}
{"nodeid": "test_foo.py::test[1]", "start": 0.000, "finish": 1.5, "outcome": "passed"}
{"nodeid": "test_foo.py::test[3]", "start": 1.5}
{"nodeid": "test_foo.py::test[3]", "start": 1.5, "finish": 2.5, "outcome": "passed"}
{"nodeid": "test_foo.py::test[5]", "start": 2.5}
{"nodeid": "test_foo.py::test[5]", "start": 2.5, "finish": 3.5, "outcome": "passed"}
{"nodeid": "test_foo.py::test[7]", "start": 3.5}
{"nodeid": "test_foo.py::test[7]", "start": 3.5, "finish": 4.5, "outcome": "passed"}
{"nodeid": "test_foo.py::test[8]", "start": 4.5}
{"nodeid": "test_foo.py::test[8]", "start": 4.5, "finish": 5.5, "outcome": "passed"}

If there is a crash or a flaky failure in the tests of the worker gw1, one can take that file from the CI server and execute the tests in the same order with:

$ pytest --replay=.pytest-replay-gw1.txt

Hopefully this will make it easier to reproduce the problem and fix it.

Replaying Multiple Files in Parallel

Version added: 1.7

When you have multiple replay files from a distributed test run (such as .pytest-replay-gw0.txt, .pytest-replay-gw1.txt), you can replay them all at once in parallel with pytest-xdist installed. This is useful when you want to reproduce the exact execution environment that occurred during a CI run with multiple workers.

Simply pass multiple replay files to the --replay option:

$ pytest --replay .pytest-replay-gw0.txt .pytest-replay-gw1.txt

pytest-replay will automatically:

  • Configure pytest-xdist with the appropriate number of workers (one per replay file)

  • Assign each replay file to a dedicated worker using xdist groups

  • Execute tests in parallel while maintaining the order within each replay file

Note: Multiple replay files require pytest-xdist to be installed. If you try to use multiple files without xdist, pytest-replay will show an error message.

Important: When using multiple replay files, you cannot manually specify xdist options like -n, --dist, --numprocesses, or --maxprocesses, as these are automatically configured based on the number of replay files provided.

Additional metadata

Version added: 1.6

In cases where it is necessary to add new metadata to the replay file to make the test reproducible, pytest-replay provides a fixture called replay_metadata that allows new information to be added using the metadata attribute.

Example:

import pytest
import numpy as np
import random

@pytest.fixture
def rng(replay_metadata):
    seed = replay_metadata.metadata.setdefault("seed", random.randint(0, 100))
    return np.random.default_rng(seed=seed)

def test_random(rng):
    data = rng.standard_normal((100, 100))
    assert data.shape == (100, 100)

When using it with pytest-replay it generates a replay file similar to

{"nodeid": "test_bar.py::test_random", "start": 0.000}
{"nodeid": "test_bar.py::test_random", "start": 0.000, "finish": 1.5, "outcome": "passed", "metadata": {"seed": 12}}

FAQ

  1. pytest has its own cache, why use a different mechanism?

    The internal cache saves its data using json, which is not suitable in the advent of a crash because the file will not be readable.

  2. Shouldn’t the ability of selecting tests from a file be part of the pytest core?

    Sure, but let’s try to use this a bit as a separate plugin before proposing its inclusion into the core.

Installation

You can install pytest-replay via pip from PyPI:

$ pip install pytest-replay

Or with conda:

$ conda install -c conda-forge pytest-replay

Contributing

Contributions are very welcome.

Tests can be run with tox if you are using a native Python installation.

To run tests with conda, first create a virtual environment and execute tests from there (conda with Python 3.5+ in the root environment):

$ python -m venv .env
$ .env\scripts\activate
$ pip install -e . pytest-xdist
$ pytest tests

Releases

Follow these steps to make a new release:

  1. Create a new branch release-X.Y.Z from master;

  2. Update CHANGELOG.rst;

  3. Open a PR;

  4. After it is green and approved, push a new tag in the format X.Y.Z;

GitHub Actions will deploy to PyPI automatically.

Afterwards, update the recipe in conda-forge/pytest-replay-feedstock.

License

Distributed under the terms of the MIT license.

Issues

If you encounter any problems, please file an issue along with a detailed description.

Metadata

Release files for pytest-replay 1.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-replay 1.8.0
File Size Uploaded Provenance
pytest_replay-1.8.0.tar.gz 18.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-replay 1.8.0
File Interpreter ABI Platform
pytest_replay-1.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.5 kB

Release files / pytest_replay-1.8.0.tar.gz

Download URL pytest_replay-1.8.0.tar.gz
Size 18.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f17c97cfa947c7d49c4f3aab96ebf5fa56e6437a77ea409fd3e5a3a4fa05a563
BLAKE2b-256 checksum
How to use checksums
f25deab2fa0cb44c1315d3b2b11c9cc6d4b6b0eb7d26a981d20c7876a69a25a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 26, 2026.

Transparency log

Release files / pytest_replay-1.8.0-py3-none-any.whl

Download URL pytest_replay-1.8.0-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
01de608bc8f941b09d00813a5894df5f4277d6e9b53016866d0d6d7f25913b93
BLAKE2b-256 checksum
How to use checksums
6ffee10b1b54b948db97771b720a1821763cbd42cbd40e41cdb0796278e3d31d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 26, 2026.

Transparency log

Security for pytest-replay 1.8.0

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.

Select from 2 files

Attestation for pytest_replay-1.8.0.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 26, 2026.

Transparency log

A 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.

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