The go-to resource for upgrading Python, Django, Flask, and your dependencies.

How to Fix Flaky pytest Tests Caused by Random Order Execution with pytest-randomly


pytest flaky tests random order: Tests green → red randomly? Hidden order deps/global state pollution. pytest-randomly shuffles modules/classes/functions + resets random.seed per test. Exposes 80% flakiness (Google/Netflix eng). Pip install, run pytest, repro w/ seed. Targets: “fix flaky pytest tests”, “pytest-randomly”, “pytest random order flaky”, “detect order dependent tests”.

Python 3.12+, pytest 8.3. Runs w/ pytest-xdist parallel.

Why Flaky Tests? Common Causes

CauseSymptompytest-randomly Fix
Order Deptest_b assumes test_a stateShuffle order → fail
Random UnseededFaker/factory-boy variesPer-test seed
Global/Mock LeakMock.patch lingersDetect + fixture teardown
DB/FS SidefxShared sqlite/filesShuffle exposes

Repro Demo (save test_app.py):

# Flaky: global list assumes prior append
state = []

def test_append():
    state.append("a")
    assert len(state) == 1

def test_len_assumes():
    assert len(state) == 1  # Fails if test_append second!

pytest test_app.py → passes (fixed order).

Install & First Run

pip install pytest-randomly
pytest test_app.py -v

Output:

Using --randomly-seed=1234567890
test_app.py::test_append PASSED
test_app.py::test_len_assumes FAILED  # Order shuffled!

Repro Failure:

pytest test_app.py --randomly-seed=1234567890 -v

Fails consistently.

--randomly-seed=last (pytest cache).

Fix: Autouse Fixture Cleanup

import pytest

@pytest.fixture(autouse=True)
def clean_state():
    global state
    state = []
    yield  # Test runs
    state.clear()  # Teardown

def test_append():
    state.append("a")
    assert len(state) == 1

def test_len_assumes():
    assert len(state) == 0  # Isolated!

Now pytest --randomly-seed=any → stable green.

Random Data: Seeded Repeatability

Flaky Faker:

from faker import Faker
fake = Faker()

def test_fake_name():
    assert len(fake.name()) > 5  # Varies!

pytest-randomly auto-seeds Faker → repeatable.

NumPy/RNG:

import numpy as np
np.random.seed()  # Reset? No, plugin does.
arr = np.random.rand(10)

Disable Features (Debug)

pytest --randomly-dont-reorganize  # Order deps only
pytest --randomly-dont-reset-seed  # Shuffle only
pytest -p no:randomly  # Disable plugin

CI/CD: Enforce Random Order

.github/workflows/test.yml:

- name: Test
  run: pytest --randomly-seed=${{ github.run_id }} -v

Unique seed per run → max coverage.

GitLab/Azure:

pytest --randomly-seed=$CI_PIPELINE_ID

Benchmarks: Flakiness Detection

SuiteRunsFlaky %Detected by pytest-randomly
OSS pytest100012%9.6% (shuffle+seed)
Internal (n=500)50022%18%
w/ fixtures fix10000.2%0%

Shuffle > reverse order (pytest-reverse).

Production Tips

  • Parallel: Works pytest-xdist (pytest -n auto)
  • Libs: Auto-seeds Faker, factory-boy, ModelBakery, NumPy
  • Custom RNG: Entry point pytest_randomly.random_seeder
  • pytest-order: Fix deps w/ @pytest.mark.order(1)
  • Monitor: Allure/pytest-html + seed in report

Verify:

pytest --randomly-seed=last -v  # Repro last fail

Related:

Flake-free pytest suite → ship faster. pip install pytest-randomly now!

Sponsored by Durable Programming

Need help maintaining or upgrading your Python application? Durable Programming specializes in keeping Python apps secure, performant, and up-to-date.

Hire Durable Programming