Skip to content

Commit 8eb2ae6

Browse files
author
Sylvain MARIE
committed
2 parents 8e30ab0 + 998429f commit 8eb2ae6

File tree

5 files changed

+49
-6
lines changed

5 files changed

+49
-6
lines changed

docs/api_reference.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ CaseType = Union[Callable, Type, ModuleRef]
274274

275275
A decorator for test functions or fixtures, to parametrize them based on test cases. It works similarly to [`@pytest.mark.parametrize`](https://docs.pytest.org/en/stable/parametrize.html): argnames represent a coma-separated string of arguments to inject in the decorated test function or fixture. The argument values (`argvalues` in [`@pytest.mark.parametrize`](https://docs.pytest.org/en/stable/parametrize.html)) are collected from the various case functions found according to `cases`, and injected as lazy values so that the case functions are called just before the test or fixture is executed.
276276

277-
By default (`cases=AUTO`) the list of test cases is automatically drawn from the python module file named `test_<name>_cases.py` or if not found, `case_<name>.py`, where `test_<name>` is the current module name.
277+
By default (`cases=AUTO`) the list of test cases is automatically drawn from the python module file named `test_<name>_cases.py` or if not found, `cases_<name>.py`, where `test_<name>` is the current module name.
278278

279279
Finally, the `cases` argument also accepts an explicit case function, cases-containing class, module or module name; or a list containing any mix of these elements. Note that both absolute and relative module names are supported.
280280

@@ -293,7 +293,7 @@ argvalues = get_parametrize_args(host_class_or_module_of_f, cases_funs)
293293

294294
- `argnames`: same than in `@pytest.mark.parametrize`
295295

296-
- `cases`: a case function, a class containing cases, a module object or a module name string (relative module names accepted). Or a list of such items. You may use `THIS_MODULE` or `'.'` to include current module. `AUTO` (default) means that the module named `test_<name>_cases.py` or if not found, `case_<name>.py`, will be loaded, where `test_<name>.py` is the module file of the decorated function. When a module is listed, all of its functions matching the `prefix`, `filter` and `has_tag` are selected, including those functions nested in classes following naming pattern `*Case*`. Nested subclasses are taken into account, as long as they follow the `*Case*` naming pattern. When classes are explicitly provided in the list, they can have any name and do not need to follow this `*Case*` pattern.
296+
- `cases`: a case function, a class containing cases, a module object or a module name string (relative module names accepted). Or a list of such items. You may use `THIS_MODULE` or `'.'` to include current module. `AUTO` (default) means that the module named `test_<name>_cases.py` or if not found, `cases_<name>.py`, will be loaded, where `test_<name>.py` is the module file of the decorated function. When a module is listed, all of its functions matching the `prefix`, `filter` and `has_tag` are selected, including those functions nested in classes following naming pattern `*Case*`. Nested subclasses are taken into account, as long as they follow the `*Case*` naming pattern. When classes are explicitly provided in the list, they can have any name and do not need to follow this `*Case*` pattern.
297297

298298
- `prefix`: the prefix for case functions. Default is 'case_' but you might wish to use different prefixes to denote different kind of cases, for example 'data_', 'algo_', 'user_', etc.
299299

docs/changelog.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
### 3.8.2 (in progress) - bugfixes
4+
5+
- Corrected API documentation (and comments) for the second file-name
6+
pattern for `AUTO`-cases lookup (`cases_<name>.py` instead of
7+
`case_<name>.py`). PR [#320](https://github.com/smarie/python-pytest-cases/pull/320)
8+
by [@michele-riva](https://github.com/michele-riva).
9+
- Fixed `AssertionError` on `AUTO` cases outside a 'normal' test module.
10+
Fixes [#309](https://github.com/smarie/python-pytest-cases/issues/309). PR
11+
[#320](https://github.com/smarie/python-pytest-cases/pull/320) by
12+
[@michele-riva](https://github.com/michele-riva).
13+
314
### 3.8.1 - bugfixes
415

516
- Fixed `ScopeMismatch` with parametrized cases in non-trivial test

src/pytest_cases/case_parametrizer_new.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def parametrize_with_cases(argnames, # type: Union[str, List[str]
106106
:param argnames: same than in @pytest.mark.parametrize
107107
:param cases: a case function, a class containing cases, a module object or a module name string (relative module
108108
names accepted). Or a list of such items. You may use `THIS_MODULE` or `'.'` to include current module.
109-
`AUTO` (default) means that the module named `test_<name>_cases.py` or if not found, `case_<name>.py`, will be
109+
`AUTO` (default) means that the module named `test_<name>_cases.py` or if not found, `cases_<name>.py`, will be
110110
loaded, where `test_<name>.py` is the module file of the decorated function. When a module is listed, all of
111111
its functions matching the `prefix`, `filter` and `has_tag` are selected, including those functions nested in
112112
classes following naming pattern `*Case*`. Nested subclasses are taken into account, as long as they follow the
@@ -224,7 +224,7 @@ def get_all_cases(parametrization_target=None, # type: Callable
224224
names accepted). Or a list of such items. You may use `THIS_MODULE` or `'.'` to include current module.
225225
`AUTO` (default) means that the module named `test_<name>_cases.py` will be loaded, where `test_<name>.py` is
226226
the module file of the decorated function. `AUTO2` allows you to use the alternative naming scheme
227-
`case_<name>.py`. When a module is listed, all of its functions matching the `prefix`, `filter` and `has_tag`
227+
`cases_<name>.py`. When a module is listed, all of its functions matching the `prefix`, `filter` and `has_tag`
228228
are selected, including those functions nested in classes following naming pattern `*Case*`. When classes are
229229
explicitly provided in the list, they can have any name and do not need to follow this `*Case*` pattern.
230230
:param prefix: the prefix for case functions. Default is 'case_' but you might wish to use different prefixes to
@@ -299,7 +299,18 @@ def get_all_cases(parametrization_target=None, # type: Callable
299299
else:
300300
# module
301301
if c is AUTO:
302-
# First try `test_<name>_cases.py` Then `case_<name>.py`
302+
# Make sure we're in a test_<xxx>.py-like module.
303+
# We cannot accept AUTO cases in, e.g., conftest.py
304+
# as we don't know what to look for. We complain here
305+
# rather than raising AssertionError in the call to
306+
# import_default_cases_module. See #309.
307+
if not caller_module_name.split('.')[-1].startswith('test_'):
308+
raise ValueError(
309+
'Cannot use `cases=AUTO` in file "%s". `cases=AUTO` is '
310+
'only allowed in files whose name starts with "test_" '
311+
% caller_module_name
312+
)
313+
# First try `test_<name>_cases.py` Then `cases_<name>.py`
303314
c = import_default_cases_module(caller_module_name)
304315

305316
elif c is THIS_MODULE or c == '.':
@@ -680,7 +691,7 @@ def import_default_cases_module(test_module_name):
680691
try:
681692
cases_module = import_module(cases_module_name1)
682693
except ModuleNotFoundError:
683-
# Then try `case_<name>.py`
694+
# Then try `cases_<name>.py`
684695
parts = test_module_name.split('.')
685696
assert parts[-1][0:5] == 'test_'
686697
cases_module_name2 = "%s.cases_%s" % ('.'.join(parts[:-1]), parts[-1][5:])
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from pytest_cases import fixture, get_all_cases
2+
from pytest_cases.common_others import AUTO
3+
4+
5+
def mock_parameterization_target():
6+
"""A callable to use as parametrization target."""
7+
8+
9+
@fixture
10+
def get_all_cases_auto_fails():
11+
"""Fail because we ask for AUTO cases in a non-'test_<...>' file."""
12+
def _fail():
13+
get_all_cases(mock_parameterization_target, cases=AUTO)
14+
return _fail
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
import pytest
3+
4+
5+
def test_get_all_cases_auto_raises(get_all_cases_auto_fails):
6+
with pytest.raises(ValueError):
7+
get_all_cases_auto_fails()

0 commit comments

Comments
 (0)