Skip to content

Commit cec0568

Browse files
author
Sylvain MARIE
committed
Pytest marks such as @pytest.mark.skipif can now be used on case functions. As a consequence, get_all_cases is now the recommended function to use instead of extract_cases_from_module to perform manual collection. Indeed get_all_cases correctly prepares the resulting parameters list so that pytest sees the marks. Fixed #21
1 parent 9d0396a commit cec0568

File tree

7 files changed

+40
-13
lines changed

7 files changed

+40
-13
lines changed

docs/api_reference.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@ is equivalent to:
175175

176176
```python
177177
import pytest
178-
from pytest_cases import extract_cases_from_module, CaseData
178+
from pytest_cases import get_all_cases, CaseData
179179

180180
# import the module containing the test cases
181181
import test_foo_cases
182182

183183
# manually list the available cases
184-
cases = extract_cases_from_module(test_foo_cases)
184+
cases = get_all_cases(module=test_foo_cases)
185185

186186
# parametrize the test function manually
187187
@pytest.mark.parametrize('case_data', cases, ids=str)
@@ -196,7 +196,7 @@ def test_foo(case_data: CaseData):
196196

197197
### `CaseDataGetter`
198198

199-
A proxy for a test case. Instances of this class are created by `@cases_data` or `extract_cases_from_module`. It provides a single method:
199+
A proxy for a test case. Instances of this class are created by `@cases_data` or `get_all_cases`. It provides a single method:
200200

201201
`get(self, *args, **kwargs) -> Union[CaseData, Any]`
202202

docs/usage/advanced.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,13 @@ The `@cases_data` decorator is just syntactic sugar for the following two-steps
396396
397397
```python
398398
import pytest
399-
from pytest_cases import extract_cases_from_module, CaseData
399+
from pytest_cases import get_all_cases, CaseData
400400
401401
# import the module containing the test cases
402402
import test_foo_cases
403403
404404
# manually list the available cases
405-
cases = extract_cases_from_module(test_foo_cases)
405+
cases = get_all_cases(module=test_foo_cases)
406406
407407
# parametrize the test function manually
408408
@pytest.mark.parametrize('case_data', cases, ids=str)

pytest_cases/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
pass
77

88
from pytest_cases.main import cases_data, CaseDataGetter, cases_fixture, pytest_fixture_plus, \
9-
unfold_expected_err, get_all_cases, extract_cases_from_module, THIS_MODULE
9+
unfold_expected_err, get_all_cases, THIS_MODULE
1010

1111
__all__ = [
1212
# the 3 submodules
1313
'main', 'case_funcs', 'common',
1414
# all symbols imported above
1515
'cases_data', 'CaseData', 'CaseDataGetter', 'cases_fixture', 'pytest_fixture_plus',
1616
'unfold_expected_err', 'get_all_cases',
17-
'extract_cases_from_module',
1817
'case_name', 'Given', 'ExpectedNormal', 'ExpectedError',
1918
'test_target', 'case_tags', 'THIS_MODULE', 'cases_generator', 'MultipleStepsCaseData'
2019
]

pytest_cases/main.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
class CaseDataGetter(six.with_metaclass(ABCMeta)):
4646
"""
47-
A proxy for a test case. Instances of this class are created by `@cases_data` or `extract_cases_from_module`.
47+
A proxy for a test case. Instances of this class are created by `@cases_data` or `get_all_cases`.
4848
4949
It provides a single method: `get(self, *args, **kwargs) -> CaseData`
5050
This method calls the actual underlying case with arguments propagation, and returns the result.
@@ -60,6 +60,13 @@ def get(self, *args, **kwargs):
6060
:return:
6161
"""
6262

63+
def get_marks(self):
64+
"""
65+
Returns the pytest marks on this case, if any
66+
:return:
67+
"""
68+
return []
69+
6370
def get_for(self, key):
6471
# type: (...) -> CaseData
6572
"""
@@ -112,6 +119,16 @@ def __str__(self):
112119
def __repr__(self):
113120
return "Test Case Data generator - [" + str(self) + "] - " + str(self.f)
114121

122+
def get_marks(self):
123+
"""
124+
Overrides default implementation to return the marks that are on the case function
125+
:return:
126+
"""
127+
try:
128+
return self.f.pytestmark
129+
except AttributeError:
130+
return []
131+
115132
def get(self, *args, **kwargs):
116133
# type: (...) -> Union[CaseData, Any]
117134
"""
@@ -171,7 +188,7 @@ def foo_fixture(case_data: CaseData):
171188
172189
```python
173190
import pytest
174-
from pytest_cases import extract_cases_from_module, CaseData
191+
from pytest_cases import get_all_cases, CaseData
175192
176193
# import the module containing the test cases
177194
import test_foo_cases
@@ -525,6 +542,9 @@ def get_all_cases(cases=None, # type: Union[Callable[[Any], Any],
525542
m = sys.modules[this_module_object.__module__] if module is THIS_MODULE else module
526543
_cases = extract_cases_from_module(m, has_tag=has_tag, filter=filter)
527544

545+
# create the pytest parameters to handle pytest marks
546+
_cases = [c if len(c.get_marks()) == 0 else pytest.param(c, marks=c.get_marks()) for c in _cases]
547+
528548
return _cases
529549

530550

pytest_cases/tests/advanced/test_memoize_generators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pytest_cases import cases_data, THIS_MODULE, cases_generator, CaseDataGetter, extract_cases_from_module
1+
from pytest_cases import cases_data, THIS_MODULE, cases_generator, CaseDataGetter, get_all_cases
22
from pytest_cases.tests.utils import nb_pytest_parameters, get_pytest_param
33

44
try: # python 3+: type hints
@@ -40,7 +40,7 @@ def test_b(case_data # type: CaseDataGetter
4040
def test_assert_cases_are_here():
4141
"""Asserts that the 3 cases are generated"""
4242
import sys
43-
cases = extract_cases_from_module(sys.modules[case_gen.__module__])
43+
cases = get_all_cases(module=sys.modules[case_gen.__module__])
4444
assert len(cases) == 3
4545

4646

pytest_cases/tests/simple/test_main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
from pytest_cases.tests.example_code import super_function_i_want_to_test
33

4-
from pytest_cases import cases_data, CaseDataGetter, unfold_expected_err, extract_cases_from_module
4+
from pytest_cases import cases_data, CaseDataGetter, unfold_expected_err, get_all_cases
55
from pytest_cases.tests.simple import test_main_cases
66

77

@@ -39,7 +39,7 @@ def test_with_cases_decorated(case_data # type: CaseDataGetter
3939

4040

4141
# ----------------- Advanced: Manual way: -------------
42-
cases = extract_cases_from_module(test_main_cases)
42+
cases = get_all_cases(module=test_main_cases)
4343

4444

4545
@pytest.mark.parametrize('case_data', cases, ids=str)

pytest_cases/tests/simple/test_main_cases.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import pytest
2+
13
try: # python 3+
24
from math import inf
35
except ImportError:
@@ -64,3 +66,9 @@ def is_good_error(e):
6466
return type(e) is InfiniteInput and e.args == ('b',)
6567

6668
return ins, None, is_good_error
69+
70+
71+
@pytest.mark.skip("skipped on purpose")
72+
def case_skipped():
73+
""" A skipped case """
74+
return

0 commit comments

Comments
 (0)