Skip to main content

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

Project description

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.

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.

Project details


Download files

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

Source Distribution

pytest_replay-1.5.3.tar.gz (12.6 kB view details)

Uploaded Source

Built Distribution

pytest_replay-1.5.3-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file pytest_replay-1.5.3.tar.gz.

File metadata

  • Download URL: pytest_replay-1.5.3.tar.gz
  • Upload date:
  • Size: 12.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for pytest_replay-1.5.3.tar.gz
Algorithm Hash digest
SHA256 e1a6d2e4f442a2793d75d8c24f59f5632c31494cb84cda046e9f97293ad51fdc
MD5 817966001c4670a6d52e7f712d544016
BLAKE2b-256 3fd4170de7c24bd9b1dea30fc7c569b4e670135c45f6214af8b4190928f4dcb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_replay-1.5.3.tar.gz:

Publisher: deploy.yml on ESSS/pytest-replay

Attestations:

File details

Details for the file pytest_replay-1.5.3-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_replay-1.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5339135ee3c86adb89614840a437735d9f46de75acdd64d4c5a6b72fe55a66d8
MD5 1b4cb3c610f4cb20456ec60b90304c7c
BLAKE2b-256 7f53e31d88b6392063d5ab2278c4b7a88cd828c0230ccb5e13c3a471d4b399a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_replay-1.5.3-py3-none-any.whl:

Publisher: deploy.yml on ESSS/pytest-replay

Attestations:

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page