diff --git a/docs/api_reference.md b/docs/api_reference.md index a8800ddf..6dfdf92c 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -325,7 +325,7 @@ CaseType = Union[Callable, Type, ModuleRef] 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. -By default (`cases=AUTO`) the list of test cases is automatically drawn from the python module file named `test__cases.py` or if not found, `cases_.py`, where `test_` is the current module name. +By default (`cases=AUTO`) the list of test cases is automatically drawn from the python module file named `test__cases.py` or if not found, `cases_.py`, where `test_` is the current module name. Also works for `tests.py` (`tests_cases.py`). 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. diff --git a/docs/changelog.md b/docs/changelog.md index b00ef711..cfa1822c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,6 +6,8 @@ defined in a case class. Fixes [#351](https://github.com/smarie/python-pytest-cases/issues/351). PR [#361](https://github.com/smarie/python-pytest-cases/pull/361) by [@michele-riva](https://github.com/michele-riva). +- Allow `tests.py` to find tests from `tests_cases.py`. Fixes [#366](https://github.com/smarie/python-pytest-cases/issues/366). + PR [#344](https://github.com/smarie/python-pytest-cases/pull/344) by [@last-partizan](https://github.com/last-partizan). ### 3.9.1 - support for python 3.14 and pytest 8.4 diff --git a/setup.cfg b/setup.cfg index 6218a904..fd7a91c2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -87,6 +87,7 @@ test = pytest # pytest default configuration [tool:pytest] testpaths = tests/ +python_files = tests.py test_*.py *_tests.py markers = black: dummy mark. fast: dummy mark. diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index ddd36bb8..90d47e74 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -304,7 +304,7 @@ def get_all_cases(parametrization_target=None, # type: Callable # as we don't know what to look for. We complain here # rather than raising AssertionError in the call to # import_default_cases_module. See #309. - if not caller_module_name.split('.')[-1].startswith('test_'): + if not _has_test_prefix(caller_module_name.split('.')[-1]): raise ValueError( 'Cannot use `cases=AUTO` in file "%s". `cases=AUTO` is ' 'only allowed in files whose name starts with "test_" ' @@ -324,6 +324,11 @@ def get_all_cases(parametrization_target=None, # type: Callable if matches_tag_query(c, has_tag=has_tag, filter=filters)] +def _has_test_prefix(module_name): # type: (str) -> bool + prefixes = ('test_', 'tests') + return any(module_name.startswith(p) for p in prefixes) + + def get_parametrize_args(host_class_or_module, # type: Union[Type, ModuleType] cases_funs, # type: List[Callable] prefix, # type: str @@ -694,7 +699,7 @@ def import_default_cases_module(test_module_name): except ModuleNotFoundError: # Then try `cases_.py` parts = test_module_name.split('.') - assert parts[-1][0:5] == 'test_' + assert _has_test_prefix(parts[-1]) cases_module_name2 = "%s.cases_%s" % ('.'.join(parts[:-1]), parts[-1][5:]) try: cases_module = import_module(cases_module_name2) diff --git a/tests/cases/issues/issue_366/__init__.py b/tests/cases/issues/issue_366/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/cases/issues/issue_366/tests.py b/tests/cases/issues/issue_366/tests.py new file mode 100644 index 00000000..77d830b2 --- /dev/null +++ b/tests/cases/issues/issue_366/tests.py @@ -0,0 +1,12 @@ +from pytest_cases import get_all_cases +from pytest_cases.common_others import AUTO + + +def mock_parameterization_target(): + """A callable to use as parametrization target.""" + + +def test_get_all_cases_auto_works_in_tests_py(): + res = get_all_cases(mock_parameterization_target, cases=AUTO) + assert isinstance(res, list) and len(res) == 1 + assert res[0].__name__ == "case_one_366" diff --git a/tests/cases/issues/issue_366/tests_cases.py b/tests/cases/issues/issue_366/tests_cases.py new file mode 100644 index 00000000..a89f2ba4 --- /dev/null +++ b/tests/cases/issues/issue_366/tests_cases.py @@ -0,0 +1,2 @@ +def case_one_366(): + return 1