Deterministic pytest test sharding across CI machines
Project description
pytest-paraflow
pytest-paraflow is a pytest plugin for deterministic test sharding across machines.
Features
- Deterministic sharding by test identity (stable hash-based assignment).
- Group-based sharding via markers so related tests stay together.
- Dynamic shard count derived from total test count and desired shard size.
Install
uv add pytest-paraflow
Usage
Enable sharding by passing --paraflow-shard-id and either --paraflow-num-shards or --paraflow-target-shard-size.
Static shard count
pytest --paraflow-shard-id=0 --paraflow-num-shards=4
Dynamic shard count
pytest --paraflow-shard-id=1 --paraflow-target-shard-size=200
For N collected tests, shard count is calculated as ceil(N / target_shard_size).
Group tests by marker
import pytest
@pytest.mark.paraflow_group("db")
def test_a():
...
@pytest.mark.paraflow_group("db")
def test_b():
...
pytest \
--paraflow-shard-id=0 \
--paraflow-num-shards=3 \
--paraflow-group-marker=paraflow_group
Marker behavior:
- Tests with the same marker value are assigned to the same shard.
@pytest.mark.paraflow_group(...)is only used when--paraflow-group-marker=paraflow_groupis provided.- Without
--paraflow-group-marker, paraflow falls back to per-test (nodeid) sharding. --paraflow-group-marker=smokewith@pytest.mark.smokegroups allsmoketests together (single group key).--paraflow-group-marker=smokewith@pytest.mark.smoke("db")groups by value (for exampledb,api).--paraflow-group-markeris repeatable. If multiple configured markers exist on one test, the first configured marker wins.
CLI options
--paraflow-shard-id: current shard index (zero-based).--paraflow-num-shards: total shard count.--paraflow-target-shard-size: desired tests per shard for dynamic sizing.--paraflow-group-marker: marker name used for grouping (repeatable).
Configuration defaults
CLI option defaults are loaded from Settings (src/pytest_paraflow/config/settings.py).
You can configure them via environment variables:
PYTEST_PARAFLOW__SHARD_IDPYTEST_PARAFLOW__NUM_SHARDSPYTEST_PARAFLOW__TARGET_SHARD_SIZEPYTEST_PARAFLOW__GROUP_MARKER(JSON array, for example["paraflow_group", "smoke"])
CLI values always override environment defaults.
GitHub Actions (matrix sharding)
Example workflow template: examples/paraflow-matrix-example.yml.
Copy it into .github/workflows/ in your repository to enable CI.
It runs pytest in 4 shards via matrix (shard_id: [0, 1, 2, 3]) and limits concurrent shard jobs with:
strategy.max-parallel: 2--paraflow-shard-id=${{ matrix.shard_id }}--paraflow-num-shards=4
Validation rules
--paraflow-shard-idis required whenever sharding is enabled.- One of
--paraflow-num-shardsor--paraflow-target-shard-sizeis required. --paraflow-shard-idmust be in[0, total_shards - 1].
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_paraflow-0.1.0.tar.gz.
File metadata
- Download URL: pytest_paraflow-0.1.0.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b20b78641e18fee9c0862b93fe9a0bad8ea6c21df9dd85cbaa0d40f78a88540
|
|
| MD5 |
ab3947ae14acad8920ec0239862cdaee
|
|
| BLAKE2b-256 |
9321a0751de1ccaa47037c1d8afe67f202087ab9c19ce5a8f6b1f8da75abc2ef
|
Provenance
The following attestation bundles were made for pytest_paraflow-0.1.0.tar.gz:
Publisher:
publish-to-pypi.yml on l0kifs/pytest-paraflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_paraflow-0.1.0.tar.gz -
Subject digest:
0b20b78641e18fee9c0862b93fe9a0bad8ea6c21df9dd85cbaa0d40f78a88540 - Sigstore transparency entry: 995797717
- Sigstore integration time:
-
Permalink:
l0kifs/pytest-paraflow@841b6357ff7143ffefefdee6cf803afe41c4d37b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/l0kifs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@841b6357ff7143ffefefdee6cf803afe41c4d37b -
Trigger Event:
release
-
Statement type:
File details
Details for the file pytest_paraflow-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pytest_paraflow-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1c8926f1a3d6a827cedc34abab26001abdbd3c2632d0d64e13b5df12631c3d9
|
|
| MD5 |
1609ba00efe33642e03f486226a53072
|
|
| BLAKE2b-256 |
ef8cad22c53d7197a779305627b535257bacd4e8a2d6996e9301c28744d9fd4c
|
Provenance
The following attestation bundles were made for pytest_paraflow-0.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on l0kifs/pytest-paraflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_paraflow-0.1.0-py3-none-any.whl -
Subject digest:
c1c8926f1a3d6a827cedc34abab26001abdbd3c2632d0d64e13b5df12631c3d9 - Sigstore transparency entry: 995797719
- Sigstore integration time:
-
Permalink:
l0kifs/pytest-paraflow@841b6357ff7143ffefefdee6cf803afe41c4d37b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/l0kifs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@841b6357ff7143ffefefdee6cf803afe41c4d37b -
Trigger Event:
release
-
Statement type: