pytest-case-provider
Parametrization for pytest with fixture support, async support, class-method support, shared storage, and module-level case discovery. Declarative, typed, on-demand injection for sync, async, iterable, and async-iterable providers.
Overview
Extends pytest’s parametrization layer with case storages and containers. Containers attach case sets to test functions and test methods via inject_func and inject_method. Fixtures integrate natively. Async is supported. Matching case_*.py modules are scanned and loaded. Duplicate case names collapse to single instances.
Core Concepts
Providers
Functions that yield case values. Supported forms:
- Sync
- Async
- Iterable
- Async iterable
- Fixture-dependent
Storage
CaseStorage instances hold providers. CompositeCaseStorage merges multiple storages.
Container
CaseContainer wraps a storage and exposes:
.case().include().inject_func().inject_method()
A single container instance feeds any number of tests.
Injectors
inject_func() and inject_method() create isolated containers for direct use. .include() attaches external storages to them.
Module-Level Loading
If test_x.py exists alongside case_x.py, the plugin imports the case module and registers its providers. Tests using inject_func() or inject_method() receive matching providers. Matching is based on the type annotation of the case parameter.
Installation
pip install pytest-case-provider
Quick Start
# test_example.py
import typing
from dataclasses import dataclass
from pytest_case_provider import CaseContainer
@dataclass(frozen=True)
class MyCase:
foo: int
container = CaseContainer[MyCase]()
@container.inject_func()
def test_cases(case: MyCase) -> None:
assert isinstance(case, MyCase)
class TestGroup:
@container.inject_method()
def test_group(self, case: MyCase) -> None:
assert case.foo >= 1
@container.case()
def case_small() -> MyCase:
return MyCase(foo=1)
@container.case()
async def case_async() -> MyCase:
return MyCase(foo=999)
@container.case()
def case_range() -> typing.Iterator[MyCase]:
yield MyCase(foo=10)
Module-Level Case Files
tests/
test_math.py
case_math.py
case_math.py:
from dataclasses import dataclass
@dataclass(frozen=True)
class MathCase:
x: int
y: int
def case_x1_y2() -> MathCase:
return MathCase(1, 2)
test_math.py:
from pytest_case_provider import inject_func
from tests.case_math import MathCase
@inject_func()
def test_add(case: MathCase) -> None:
assert case.x + case.y == 3
The plugin imports case_math and binds its providers to the injector.
Pytest Expansion
test_example.py::test_cases[case_small]
test_example.py::test_cases[case_async]
test_example.py::test_cases[case_range0]
test_example.py::test_cases[case_range1]
test_example.py::TestGroup::test_group[case_small]
test_example.py::TestGroup::test_group[case_async]
test_example.py::TestGroup::test_group[case_range0]
test_example.py::TestGroup::test_group[case_range1]
Notes
- Async requires
pytest-asyncio. - AnyIO execution paths are disabled.
- Case deduplication follows provider-name semantics.
Release files for pytest-case-provider 0.4.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_case_provider-0.4.3.tar.gz | 12.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_case_provider-0.4.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.7 kB
Release files / pytest_case_provider-0.4.3.tar.gz
| Download URL | pytest_case_provider-0.4.3.tar.gz |
|---|---|
| Size | 12.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
485239d0fa251c42d080ee3dd6a93c3df5c118ced30f12a31ffea0085dcebf52
|
|
BLAKE2b-256 checksum How to use checksums |
d654420c22963328cecf9493e0b58ad60634756fec8f8e49a97ae727999e6764
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 15, 2025.
Transparency logRelease files / pytest_case_provider-0.4.3-py3-none-any.whl
| Download URL | pytest_case_provider-0.4.3-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bda93dccc0b0f9951f44a285219dc91fdc64ac8f69774c0d8a99c58cbe5c1425
|
|
BLAKE2b-256 checksum How to use checksums |
2fc98c3cb5371084e2fb319b3d31e4b5770dc23714eba2848afd7720ccde83aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 15, 2025.
Transparency log