This package allows the declaration of parametrization using type annotations and definition of test cases using a decorator.
The primary reason of using this package over the standard pytest.mark.parametrize
is readability and maintainability
of test cases especially if many test cases are defined for a single test function.
In addition, error messages are more informative compared to those provided by pytest.mark.parametrize
.
pip install pytest-parametrization-annotation
To define a parameter as parametrized, use the Parametrized
class or an instance of the Parametrized
class as an
annotation.
from typing import Annotated
from pytest_parametrization_annotation import Parametrized
# Both definitions are treated the same
def test(a: Annotated[int, Parametrized], b: Annotated[int, Parametrized()]) -> None:
...
By default, parameters annotated in this way are treated as direct parameters.
To define a parameter as indirect, use the indirect
argument when instantiating the Parametrized
class.
from typing import Annotated
from pytest_parametrization_annotation import Parametrized
def test(a: Annotated[int, Parametrized(indirect=True)]) -> None:
...
In addition, the Parametrized
class provides to methods to define default values, default
and default_factory
.
from typing import Annotated
from pytest_parametrization_annotation import Parametrized
def test(
a: Annotated[int, Parametrized(default=1)],
b: Annotated[str, Parametrized(default_factory=lambda: "Hello World!")]
) -> None:
...
To define test cases, use the case
marker.
Each parametrized argument must be reflected as keyword in the case marker.
from typing import Annotated
import pytest
from pytest_parametrization_annotation import Parametrized
@pytest.mark.case(a=1)
def test(a: Annotated[int, Parametrized]) -> None:
...
If a parametrized argument is missing from the case marker, the test suit will fail and a detailed error message will be provided.
examples/test_basic.py::test_addition | Case number 1: Failed to populate because the parameter 'b' is not provided and default is not configured.
Every case marker defines a single test case. To define multiple test cases, use multiple case markers.
from typing import Annotated
import pytest
from pytest_parametrization_annotation import Parametrized
@pytest.mark.case(a=1)
@pytest.mark.case(a=2)
@pytest.mark.case(a=3)
def test(a: Annotated[int, Parametrized]) -> None:
...
Optionally a case can be named by providing the first positional argument to the case marker. If this is not provided the default pytest naming scheme is used.
from typing import Annotated
import pytest
from pytest_parametrization_annotation import Parametrized
@pytest.mark.case("Example", a=1)
def test(a: Annotated[int, Parametrized]) -> None:
...
poetry install
poetry run ruff format
poetry run black .
poetry run mypy .
poetry run tox run-parallel