Home / Use cases / CI test hot paths
Continuous integrationCI test hot paths
Drop fixed per-invocation cost from retries, last-failed reruns, and shards without adding a plugin dependency.
The problem
CI pipelines invoke pytest repeatedly — a full run, a --lf rerun after a flake, sometimes several shards. Each invocation re-pays interpreter startup, plugin import, and collection, and pytest-xdist re-pays worker startup on top. On suites with heavy plugin import graphs, that fixed cost dominates wall clock before a single test body executes.
How rpytest solves it
- ▸rpytest ships built-in parallelism: rpytest -n auto with duration-aware load balancing, no pytest-xdist install step.
- ▸Deterministic sharding with --shard 0 --total-shards 4 splits the suite across CI jobs.
- ▸Flakiness controls — --reruns N and --flaky-report — handle unreliable tests without an extra plugin.
- ▸Where the runner can keep the daemon alive across steps, collection is paid once and reruns are near-instant RPCs.
$ rpytest -n auto --shard 0 --total-shards 4 [collection cached · 4 workers, duration-balanced] 412 passed, 3 skipped in 8.7s
- ·Some CI runners cannot keep a long-lived process alive between invocations; in that case the daemon starts fresh per step, so the gain is smaller — measure with --verify-dropin.
- ·Published benchmark figures (BENCHMARK.md) come from one machine and a synthetic 500-test suite; your ratios will differ.
Questions
+ Do I still need pytest-xdist in CI?
Not for parallel execution — rpytest -n auto is built in with duration-aware scheduling. Keep xdist only if you depend on its specific distribution semantics like dist=loadfile or loadgroup.
+ Are exit codes and JUnit XML CI-safe?
Yes. Exit codes and JUnit XML match pytest exactly by design, so your CI gates and test-report tooling keep working unchanged.