Parallel pytest for suites that cannot be made concurrency-safe.
A lane is a group of tests that share a marker and an execution environment. Each lane runs as its own pytest subprocess: it starts its environment once, runs its tests in declaration order, and overlaps only with other lanes. Nothing inside a lane ever needs to be made concurrency-proof.
| Your situation | What to reach for |
|---|---|
| Homogeneous, independent, CPU-bound unit tests | pytest-xdist. It will beat this. |
Grouping needs fit --dist loadfile / loadscope / loadgroup |
pytest-xdist. Try it first. |
| Tests share fixed ports, one DB schema, OS state, a licensed simulator, and retrofitting them all is not happening | pytest-lanes. Safe orderings become structural instead of a per-test obligation. |
| You need setup/teardown per group, not per worker | pytest-lanes. A lane is the process, so its session fixtures wrap exactly its own tests. |
| Expensive setup can't be duplicated or serialized cheaply (a 4 GB model, an in-process index, one container) | pytest-lanes. |
| Most of your suite's time sits in one huge test file | pytest-xdist. A file is a lane's atomic unit, so that file is your floor. |
The reasoning behind this table, with measured results, lives in the guide.
pip install pytest-lanes[rich] # rich gives the live progress tableYou do not have to write a partition by hand:
pytest --lanes-suggest # propose a lane config from your layout, run nothing
pytest . --lanes-auto # zero config: one lane per test subdirectory
pytest . --lanes-explain # show which lane claims each test, run nothing
pytest . # fan out: one subprocess per lane, in parallelPaste the suggestion into pytest.ini or pyproject.toml when you are
happy with it. A durable config looks like:
[pytest]
markers =
postgres_integration: postgres-backed integration tests
unit: fast unit tests
[pytest-lanes]
lanes = postgres other
subprocess_order_standard = postgres other
[pytest-lanes:postgres]
marker = postgres_integration
classifier_path_prefixes = tests/integration/
subprocess_paths = tests/integration
[pytest-lanes:other]
marker = unit
classifier_fallback = true
subprocess_ignore_other_lanes = trueWith no lane config the plugin is dormant, and pytest -k foo,
pytest -m unit, or pytest path/to/test.py always run as plain pytest.
-s and --pdb keep working: lane output streams live under -s, and
pytest --lane=<name> runs one lane in-process where --pdb behaves
normally.
- Guide: when to use it, measured results, defining lanes, the full configuration and command-line references, how it works, coverage and JUnit in CI, sharding, limitations, FAQ.
- Runnable examples:
examples/demo(no Docker, 30 seconds),examples/containers(real Postgres testcontainers),examples/bench(a benchmark suite comparing execution modes). - CHANGELOG and ROADMAP.
git clone https://github.com/HuzPro/pytest-lanes
cd pytest-lanes
python -m venv .venv && . .venv/bin/activate # .venv\Scripts\activate on Windows
pip install -e .[test]
pytest