Skip to content

Commit 06bd93c

Browse files
committed
Improve error handling by using fail rather than custom exception
1 parent 3b4943f commit 06bd93c

File tree

9 files changed

+446
-56
lines changed

9 files changed

+446
-56
lines changed
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from .annotation import Parametrized
2-
from .exceptions import ParameterValueUndefined
32

43
__all__ = [
54
"Parametrized",
6-
"ParameterValueUndefined",
75
]

src/pytest_parametrization_annotation/exceptions.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/pytest_parametrization_annotation/functionality.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
from typing import Annotated, Any, Callable, Mapping, get_origin, get_type_hints
1+
from __future__ import annotations
22

3-
from _pytest.python import Metafunc
3+
from typing import Annotated, Any, Callable, Mapping, get_origin, get_type_hints, TYPE_CHECKING
4+
5+
from _pytest.outcomes import fail
46

57
from pytest_parametrization_annotation.annotation import (
68
Parametrized,
79
_Default,
810
_DefaultCallable,
911
)
10-
from pytest_parametrization_annotation.exceptions import ParameterValueUndefined
12+
13+
if TYPE_CHECKING:
14+
from _pytest.python import Metafunc
1115

1216

1317
def get_parameters_from_type_hints(func: Callable) -> dict[str, Parametrized]:
@@ -33,7 +37,7 @@ def get_parameters_from_type_hints(func: Callable) -> dict[str, Parametrized]:
3337

3438

3539
def get_parametrized_value(
36-
kwargs: Mapping[str, Any], parameter: str, meta: Parametrized
40+
kwargs: Mapping[str, Any], parameter: str, meta: Parametrized
3741
) -> Any:
3842
if parameter in kwargs:
3943
return kwargs[parameter]
@@ -57,10 +61,10 @@ def register_parametrized_cases(metafunc: Metafunc):
5761

5862
cases = []
5963
ids = []
60-
for i, marker in enumerate(markers):
64+
fails: list[tuple[str, str]] = []
65+
for i, marker in enumerate(reversed(markers)):
6166
case_id = marker.args[0] if len(marker.args) > 0 else None
6267
ids.append(case_id)
63-
6468
try:
6569
cases.append(
6670
tuple(
@@ -69,11 +73,16 @@ def register_parametrized_cases(metafunc: Metafunc):
6973
)
7074
)
7175
except KeyError as e:
72-
raise ParameterValueUndefined(
73-
function_definition.nodeid,
74-
case_id or i,
75-
e.args[0],
76-
) from e
76+
case_descriptor = f"named '{case_id}'" if case_id else f"number {i + 1}"
77+
fails.append((case_descriptor, e.args[0]))
78+
79+
if fails:
80+
fail_message = "\n".join(
81+
f"{function_definition.nodeid} | Case {case_descriptor}: Failed to populate because the parameter '{parameter}' is not provided and default is not configured." # noqa: E501
82+
for case_descriptor, parameter in fails
83+
)
84+
85+
fail(fail_message, pytrace=False)
7786

7887
metafunc.parametrize(
7988
tuple(parameters),
@@ -82,4 +91,4 @@ def register_parametrized_cases(metafunc: Metafunc):
8291
name for name, parameter in parameters.items() if parameter.indirect
8392
],
8493
ids=ids,
85-
)
94+
)

tests/templates/test_case_marker/missing_parameter.py

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{{ "from typing import Annotated" }}
2+
3+
import pytest
4+
{{ "from pytest_parametrization_annotation import Parametrized" }}
5+
6+
7+
{% for case in cases -%}
8+
@pytest.mark.case(
9+
{% if case.id != None %}"{{ case.id }}",{% endif %}
10+
{% for parameter in case.parameters -%}
11+
{{ parameter }}=1,
12+
{% endfor -%}
13+
)
14+
{% endfor %}
15+
def test(
16+
{% for parameter in parameters -%}
17+
{{ parameter }}: Annotated[int, Parametrized],
18+
{% endfor -%}
19+
) -> None:
20+
assert True
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from typing import Annotated
2+
3+
import pytest
4+
from pytest_parametrization_annotation import Parametrized
5+
6+
7+
@pytest.mark.case("example")
8+
def test(
9+
first: Annotated[int, Parametrized],
10+
second: Annotated[int, Parametrized(default=123)],
11+
):
12+
assert first == 1
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from typing import Annotated
2+
3+
import pytest
4+
from pytest_parametrization_annotation import Parametrized
5+
6+
7+
@pytest.mark.case("example")
8+
def test(
9+
first: Annotated[int, Parametrized(default_factory=lambda: 123)],
10+
second: Annotated[int, Parametrized],
11+
):
12+
assert first == 1

tests/test_case_marker.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -355,20 +355,3 @@ def test_indirect_parametrization(
355355

356356
result = pytester.runpytest()
357357
result.assert_outcomes(passed=expected_passed, failed=expected_failed)
358-
359-
360-
def test_missing_parameter(pytester):
361-
python_code = open(
362-
os.path.join(
363-
os.path.dirname(os.path.realpath(__file__)),
364-
"templates/test_case_marker/missing_parameter.py",
365-
)
366-
).read()
367-
pytester.makepyfile(python_code)
368-
369-
result = pytester.runpytest()
370-
assert (
371-
"E pytest_parametrization_annotation.exceptions.ParameterValueUndefined: test_missing_parameter.py::test | Case 'example': Failed to populate because the parameter 'second' is not provided and default is not configured." # noqa: E501
372-
in result.outlines
373-
)
374-
result.assert_outcomes(errors=1)

0 commit comments

Comments
 (0)