From b387ac6730f57ceb74cb6b843869998d683ccb7d Mon Sep 17 00:00:00 2001 From: eddiebergman Date: Mon, 21 Feb 2022 18:48:29 +0100 Subject: [PATCH 1/5] Add: `get_all_cases` doesn't require parametrization target --- docs/api_reference.md | 17 +++++-- src/pytest_cases/case_parametrizer_new.py | 34 +++++++++---- tests/cases/issues/test_issue_258.py | 62 +++++++++++++++++++++++ 3 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 tests/cases/issues/test_issue_258.py diff --git a/docs/api_reference.md b/docs/api_reference.md index 5d77d3dc..5324a3a9 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -280,7 +280,7 @@ Note that `@parametrize_with_cases` collection and parameter creation steps are ```python # Collect all cases -cases_funs = get_all_cases(f, cases=cases, prefix=prefix, +cases_funs = get_all_cases(f, cases=cases, prefix=prefix, glob=glob, has_tag=has_tag, filter=filter) # Transform the various functions found @@ -335,7 +335,7 @@ Note that you can get the same contents directly by using the [`current_cases`]( ### `get_all_cases` ```python -def get_all_cases(parametrization_target: Callable, +def get_all_cases(parametrization_target: Callable = None, cases: Union[Callable, Type, ModuleRef] = None, prefix: str = 'case_', glob: str = None, @@ -343,8 +343,19 @@ def get_all_cases(parametrization_target: Callable, filter: Callable[[Callable], bool] = None ) -> List[Callable]: ``` +Collect all cases as used with [`@parametrize_with_cases`](#parametrize_with_cases). See [`@parametrize_with_cases`](#parametrize_with_cases) for details on the parameters. -Lists all desired cases for a given `parametrization_target` (a test function or a fixture). This function may be convenient for debugging purposes. See [`@parametrize_with_cases`](#parametrize_with_cases) for details on the parameters. +This can be used to lists all desired cases for a given `parametrization_target` (a test function or a fixture) which may be convenient for debugging purposes. + + - If `cases` is `AUTO`, `"."` or contains a string module reference, `parametrization_target` must be provided. + +```python +# Without a parametrization target +cases = get_all_cases(cases=[case_1, case_2, case_3], has_tag=["banana"]) + +# With a parametrization target +cases = get_all_cases(f, cases=".", has_tag=["banana"]) +``` ### `get_parametrize_args` diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index 2cd9e026..3e4a0c1b 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -205,19 +205,20 @@ def _glob_name_filter(case_fun): return _glob_name_filter -def get_all_cases(parametrization_target, # type: Callable - cases=None, # type: Union[Callable, Type, ModuleRef] - prefix=CASE_PREFIX_FUN, # type: str - glob=None, # type: str - has_tag=None, # type: Union[str, Iterable[str]] - filter=None # type: Callable[[Callable], bool] # noqa +def get_all_cases(parametrization_target=None, # type: Optional[Callable] + cases=None, # type: Union[Callable, Type, ModuleRef] + prefix=CASE_PREFIX_FUN, # type: str + glob=None, # type: str + has_tag=None, # type: Union[str, Iterable[str]] + filter=None # type: Callable[[Callable], bool] # noqa ): # type: (...) -> List[Callable] """ Lists all desired cases for a given `parametrization_target` (a test function or a fixture). This function may be convenient for debugging purposes. See `@parametrize_with_cases` for details on the parameters. - :param parametrization_target: a test function + :param parametrization_target: a test function to get the module reference from. Required for cases that + rely on module reference. :param cases: a case function, a class containing cases, a module 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__cases.py` will be loaded, where `test_.py` is @@ -265,9 +266,23 @@ def get_all_cases(parametrization_target, # type: Callable filters += (filter,) + # Validate that we have a parametrization target + if parametrize_with_cases is None: + if any( + c is AUTO + or c is THIS_MODULE + or (isinstance(c, str) and c.beginswith(".")) + for c in cases + ): + raise ValueError( + "Cases beginning with '.' or using AUTO require a parametrization target," + " please use `get_all_cases(target_func, cases=...)`" + ) + # parent package - caller_module_name = getattr(parametrization_target, '__module__', None) - parent_pkg_name = '.'.join(caller_module_name.split('.')[:-1]) if caller_module_name is not None else None + if parametrization_target is not None: + caller_module_name = getattr(parametrization_target, '__module__', None) + parent_pkg_name = '.'.join(caller_module_name.split('.')[:-1]) if caller_module_name is not None else None # start collecting all cases cases_funs = [] @@ -286,6 +301,7 @@ def get_all_cases(parametrization_target, # type: Callable else: raise ValueError("Unsupported case function: %r" % c) else: + # module if c is AUTO: # First try `test__cases.py` Then `case_.py` diff --git a/tests/cases/issues/test_issue_258.py b/tests/cases/issues/test_issue_258.py new file mode 100644 index 00000000..59d99df0 --- /dev/null +++ b/tests/cases/issues/test_issue_258.py @@ -0,0 +1,62 @@ +# Authors: Eddie Bergmane +# + All contributors to +# +# License: 3-clause BSD, +# +# Issue: https://github.com/smarie/python-pytest-cases/issues/258 +from pytest_cases import get_all_cases, case, parametrize_with_cases + + +@case(tags=["a", "banana"]) +def case_1(): + return "a_banana" + + +@case(tags=["a"]) +def case_2(): + return "a" + + +@case(tags=["b", "banana"]) +def case_3(): + return "b_banana" + + +@case(tags=["b"]) +def case_4(): + return "b" + + +all_cases = get_all_cases(cases=[case_1, case_2, case_3, case_4]) + +a_cases = get_all_cases(cases=all_cases, has_tag="a") +b_cases = get_all_cases(cases=all_cases, has_tag="b") + +banana_cases = get_all_cases(cases=a_cases + b_cases, has_tag=["banana"]) + + +@parametrize_with_cases("word", cases=all_cases) +def test_all(word): + assert word in ["a", "a_banana", "b", "b_banana"] + + +@parametrize_with_cases("word", cases=a_cases) +def test_a(word): + assert "a" in word + + +@parametrize_with_cases("word", cases=b_cases) +def test_b(word): + assert "b" in word + + +@parametrize_with_cases("word", cases=banana_cases) +def test_banana(word): + assert "banana" in word + + +def test_get_cases_without_parametrization_target(): + assert len(list(all_cases)) == 4 + assert len(list(a_cases)) == 2 + assert len(list(b_cases)) == 2 + assert len(list(banana_cases)) == 2 From 83e442e2f8169ee495255f0ec1b19ee667cb8c47 Mon Sep 17 00:00:00 2001 From: eddiebergman Date: Mon, 21 Feb 2022 18:59:25 +0100 Subject: [PATCH 2/5] Fix: Make any `parametrization_target` required for string module ref --- docs/api_reference.md | 2 +- src/pytest_cases/case_parametrizer_new.py | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/api_reference.md b/docs/api_reference.md index 5324a3a9..c21e4fe7 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -347,7 +347,7 @@ Collect all cases as used with [`@parametrize_with_cases`](#parametrize_with_cas This can be used to lists all desired cases for a given `parametrization_target` (a test function or a fixture) which may be convenient for debugging purposes. - - If `cases` is `AUTO`, `"."` or contains a string module reference, `parametrization_target` must be provided. + - If `cases` is `AUTO` or contains a string module reference, `parametrization_target` must be provided. ```python # Without a parametrization target diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index 3e4a0c1b..b72058e4 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -205,7 +205,7 @@ def _glob_name_filter(case_fun): return _glob_name_filter -def get_all_cases(parametrization_target=None, # type: Optional[Callable] +def get_all_cases(parametrization_target=None, # type: Callable cases=None, # type: Union[Callable, Type, ModuleRef] prefix=CASE_PREFIX_FUN, # type: str glob=None, # type: str @@ -266,14 +266,9 @@ def get_all_cases(parametrization_target=None, # type: Optional[Callable] filters += (filter,) - # Validate that we have a parametrization target + # Validate that we have a parametrization target if required for retrieving cases if parametrize_with_cases is None: - if any( - c is AUTO - or c is THIS_MODULE - or (isinstance(c, str) and c.beginswith(".")) - for c in cases - ): + if any(c is AUTO or c is THIS_MODULE or isinstance(c, str) for c in cases): raise ValueError( "Cases beginning with '.' or using AUTO require a parametrization target," " please use `get_all_cases(target_func, cases=...)`" @@ -301,7 +296,6 @@ def get_all_cases(parametrization_target=None, # type: Optional[Callable] else: raise ValueError("Unsupported case function: %r" % c) else: - # module if c is AUTO: # First try `test__cases.py` Then `case_.py` From b04ab007a26f0728a6794564b4cf1ab67f9ac229 Mon Sep 17 00:00:00 2001 From: eddiebergman Date: Tue, 22 Feb 2022 13:06:40 +0100 Subject: [PATCH 3/5] Fix: bad variables name --- src/pytest_cases/case_parametrizer_new.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index b72058e4..69347c0b 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -267,7 +267,7 @@ def get_all_cases(parametrization_target=None, # type: Callable filters += (filter,) # Validate that we have a parametrization target if required for retrieving cases - if parametrize_with_cases is None: + if parametrization_target is None: if any(c is AUTO or c is THIS_MODULE or isinstance(c, str) for c in cases): raise ValueError( "Cases beginning with '.' or using AUTO require a parametrization target," From 73a29e868f289d9034e283f20f69a459831317da Mon Sep 17 00:00:00 2001 From: eddiebergman Date: Tue, 22 Feb 2022 13:33:43 +0100 Subject: [PATCH 4/5] Add: testing for string module references and AUTO --- src/pytest_cases/case_parametrizer_new.py | 17 ++++------ tests/cases/issues/issue_258/__init__.py | 0 tests/cases/issues/issue_258/cases.py | 10 ++++++ .../cases/issues/issue_258/cases_issue_258.py | 11 +++++++ .../issues/{ => issue_258}/test_issue_258.py | 31 ++++++++++++++----- 5 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 tests/cases/issues/issue_258/__init__.py create mode 100644 tests/cases/issues/issue_258/cases.py create mode 100644 tests/cases/issues/issue_258/cases_issue_258.py rename tests/cases/issues/{ => issue_258}/test_issue_258.py (61%) diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index 69347c0b..b335ba3d 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -37,7 +37,7 @@ from .fixture_core1_unions import USED, NOT_USED from .fixture_core2 import CombinedFixtureParamValue, fixture -from .fixture__creation import check_name_available, CHANGE +from .fixture__creation import check_name_available, get_caller_module, CHANGE from .fixture_parametrize_plus import fixture_ref, _parametrize_plus, FixtureParamAlternative, ParamAlternative, \ SingleParamAlternative, MultiParamAlternative, FixtureRefItem @@ -266,18 +266,13 @@ def get_all_cases(parametrization_target=None, # type: Callable filters += (filter,) - # Validate that we have a parametrization target if required for retrieving cases - if parametrization_target is None: - if any(c is AUTO or c is THIS_MODULE or isinstance(c, str) for c in cases): - raise ValueError( - "Cases beginning with '.' or using AUTO require a parametrization target," - " please use `get_all_cases(target_func, cases=...)`" - ) - # parent package - if parametrization_target is not None: + if parametrization_target is None: caller_module_name = getattr(parametrization_target, '__module__', None) - parent_pkg_name = '.'.join(caller_module_name.split('.')[:-1]) if caller_module_name is not None else None + else: + caller_module_name = get_caller_module() + + parent_pkg_name = '.'.join(caller_module_name.split('.')[:-1]) if caller_module_name is not None else None # start collecting all cases cases_funs = [] diff --git a/tests/cases/issues/issue_258/__init__.py b/tests/cases/issues/issue_258/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/cases/issues/issue_258/cases.py b/tests/cases/issues/issue_258/cases.py new file mode 100644 index 00000000..0162ea27 --- /dev/null +++ b/tests/cases/issues/issue_258/cases.py @@ -0,0 +1,10 @@ +from pytest_cases import case + +@case +def case_1(): + return "hello world" + + +@case +def case_2(): + return "hello mars" diff --git a/tests/cases/issues/issue_258/cases_issue_258.py b/tests/cases/issues/issue_258/cases_issue_258.py new file mode 100644 index 00000000..4aad3264 --- /dev/null +++ b/tests/cases/issues/issue_258/cases_issue_258.py @@ -0,0 +1,11 @@ +from pytest_cases import case + + +@case +def case_1(): + return "hello world" + + +@case +def case_2(): + return "hello mars" diff --git a/tests/cases/issues/test_issue_258.py b/tests/cases/issues/issue_258/test_issue_258.py similarity index 61% rename from tests/cases/issues/test_issue_258.py rename to tests/cases/issues/issue_258/test_issue_258.py index 59d99df0..2edae570 100644 --- a/tests/cases/issues/test_issue_258.py +++ b/tests/cases/issues/issue_258/test_issue_258.py @@ -1,12 +1,11 @@ -# Authors: Eddie Bergmane -# + All contributors to -# -# License: 3-clause BSD, -# -# Issue: https://github.com/smarie/python-pytest-cases/issues/258 -from pytest_cases import get_all_cases, case, parametrize_with_cases +from pytest_cases import get_all_cases, case, parametrize_with_cases, parametrize +import pytest +from pytest_cases.case_parametrizer_new import AUTO +# Test behaviour without a string module ref +############################################ + @case(tags=["a", "banana"]) def case_1(): return "a_banana" @@ -60,3 +59,21 @@ def test_get_cases_without_parametrization_target(): assert len(list(a_cases)) == 2 assert len(list(b_cases)) == 2 assert len(list(banana_cases)) == 2 + + +@parametrize("ref", ['.']) +def test_get_all_cases_raises_with_module_case(ref): + with pytest.raises(ValueError, match="Cases beginning with"): + get_all_cases(cases=ref) + + +# Test behaviour with string module ref +####################################### +def test_relative_import_cases_is_none_empty(): + relative_import_cases = get_all_cases(cases=".cases") + assert len(relative_import_cases) == 2 + + +def test_auto_import_cases_is_non_empty(): + auto_import_cases = get_all_cases(cases=AUTO) + assert len(auto_import_cases) == 2 From 142f06aa4b92d149a15f248b8ae847d2d87211f7 Mon Sep 17 00:00:00 2001 From: eddiebergman Date: Tue, 22 Feb 2022 22:43:17 +0100 Subject: [PATCH 5/5] Add: Use explicit module object with `get_all_cases` --- docs/api_reference.md | 23 +++++---- src/pytest_cases/case_parametrizer_new.py | 40 ++++++++++----- tests/cases/issues/issue_258/cases.py | 6 ++- .../cases/issues/issue_258/cases_issue_258.py | 5 +- tests/cases/issues/issue_258/cases_other.py | 13 +++++ .../cases/issues/issue_258/test_issue_258.py | 51 ++++++++++--------- tests/cases/issues/issue_258/test_other.py | 11 ++++ 7 files changed, 99 insertions(+), 50 deletions(-) create mode 100644 tests/cases/issues/issue_258/cases_other.py create mode 100644 tests/cases/issues/issue_258/test_other.py diff --git a/docs/api_reference.md b/docs/api_reference.md index c21e4fe7..5579eb6d 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -47,7 +47,7 @@ def case_hi(): - `id`: the custom pytest id that should be used when this case is active. Replaces the deprecated `@case_name` decorator from v1. If no id is provided, the id is generated from case functions by removing their prefix, see [`@parametrize_with_cases(prefix='case_')`](#parametrize_with_cases). - `tags`: custom tags to be used for filtering in [`@parametrize_with_cases(has_tags)`](#parametrize_with_cases). Replaces the deprecated `@case_tags` and `@target` decorators. - + - `marks`: optional pytest marks to add on the case. Note that decorating the function directly with the mark also works, and if marks are provided in both places they are merged. @@ -343,20 +343,25 @@ def get_all_cases(parametrization_target: Callable = None, filter: Callable[[Callable], bool] = None ) -> List[Callable]: ``` -Collect all cases as used with [`@parametrize_with_cases`](#parametrize_with_cases). See [`@parametrize_with_cases`](#parametrize_with_cases) for details on the parameters. - +Collect all cases as used with [`@parametrize_with_cases`](#parametrize_with_cases). See [`@parametrize_with_cases`](#parametrize_with_cases) for more details on the parameters. This can be used to lists all desired cases for a given `parametrization_target` (a test function or a fixture) which may be convenient for debugging purposes. - - If `cases` is `AUTO` or contains a string module reference, `parametrization_target` must be provided. - ```python -# Without a parametrization target -cases = get_all_cases(cases=[case_1, case_2, case_3], has_tag=["banana"]) +# Get the cases for f that are defined in the current file +cases = get_all_cases(f, cases=".") + +# Get the cases from cases_xyz.py or test_xyz_cases.py +import test.test_xyz +xyz_cases = get_all_cases(test.test_xyz) -# With a parametrization target -cases = get_all_cases(f, cases=".", has_tag=["banana"]) +# Can be used to filter explict cases, in which case no parametrization_target is needed +filtered_cases = get_all_cases(cases=[case_1, case_2, case_3], has_tag=["banana"]) ``` + - If using a `cases` argument that requires module information, such as `"."` `AUTO` or a relative module like `".xyz"`, the value of `parametrization_target` will be used to to determine the context. + If `None` or simply left empty, it will use the module from which `get_all_cases` was called. + You can pass an explicit module object or a function, in which case the module in which it's defined will be used. + ### `get_parametrize_args` diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index b335ba3d..456a961d 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -217,8 +217,8 @@ def get_all_cases(parametrization_target=None, # type: Callable Lists all desired cases for a given `parametrization_target` (a test function or a fixture). This function may be convenient for debugging purposes. See `@parametrize_with_cases` for details on the parameters. - :param parametrization_target: a test function to get the module reference from. Required for cases that - rely on module reference. + :param parametrization_target: either an explicit module object or a function or None. If it's a function, it will + use the module it is defined in. If None is given, it will just get the module it was called from. :param cases: a case function, a class containing cases, a module 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__cases.py` will be loaded, where `test_.py` is @@ -268,9 +268,14 @@ def get_all_cases(parametrization_target=None, # type: Callable # parent package if parametrization_target is None: + parametrization_target = get_caller_module() + + if ismodule(parametrization_target): + caller_module_name = parametrization_target.__name__ + elif callable(parametrization_target): caller_module_name = getattr(parametrization_target, '__module__', None) else: - caller_module_name = get_caller_module() + raise ValueError("Can't handle parametrization_target=%s" % parametrization_target) parent_pkg_name = '.'.join(caller_module_name.split('.')[:-1]) if caller_module_name is not None else None @@ -298,6 +303,7 @@ def get_all_cases(parametrization_target=None, # type: Callable elif c is THIS_MODULE or c == '.': c = caller_module_name + new_cases = extract_cases_from_module(c, package_name=parent_pkg_name, case_fun_prefix=prefix) cases_funs += new_cases @@ -640,31 +646,41 @@ def _get_fixture_cases(module_or_class # type: Union[ModuleType, Type] return cache, imported_fixtures_list -def import_default_cases_module(f): +def import_default_cases_module(context): """ - Implements the `module=AUTO` behaviour of `@parameterize_cases`: based on the decorated test function `f`, - it finds its containing module name "test_.py" and then tries to import the python module - "test__cases.py". + Implements the `module=AUTO` behaviour of `@parameterize_cases`: based on the context + passed in. This can either a object or a decorated test function in which + case it finds its containing module name "test_.py" and then tries to import + the python module "test__cases.py". - If the module is not found it looks for the alternate file `cases_.py`. + If "test__cases.py" module is not found it looks for the alternate + file `cases_.py`. - :param f: the decorated test function + :param f: the decorated test function or a module :return: """ + if ismodule(context): + module_name = context.__name__ + elif hasattr(context, "__module__"): + module_name = context.__module__ + else: + raise ValueError("Can't get module from context %s" % context) + # First try `test__cases.py` - cases_module_name1 = "%s_cases" % f.__module__ + cases_module_name1 = "%s_cases" % module_name + try: cases_module = import_module(cases_module_name1) except ModuleNotFoundError: # Then try `case_.py` - parts = f.__module__.split('.') + parts = module_name.split('.') assert parts[-1][0:5] == 'test_' cases_module_name2 = "%s.cases_%s" % ('.'.join(parts[:-1]), parts[-1][5:]) try: cases_module = import_module(cases_module_name2) except ModuleNotFoundError: # Nothing worked - raise ValueError("Error importing test cases module to parametrize function %r: unable to import AUTO " + raise ValueError("Error importing test cases module to parametrize %r: unable to import AUTO " "cases module %r nor %r. Maybe you wish to import cases from somewhere else ? In that case" "please specify `cases=...`." % (f, cases_module_name1, cases_module_name2)) diff --git a/tests/cases/issues/issue_258/cases.py b/tests/cases/issues/issue_258/cases.py index 0162ea27..932d04a8 100644 --- a/tests/cases/issues/issue_258/cases.py +++ b/tests/cases/issues/issue_258/cases.py @@ -1,10 +1,12 @@ +# Imported explicitly or with ".cases" from pytest_cases import case + @case def case_1(): - return "hello world" + return "hello ." @case def case_2(): - return "hello mars" + return "hi ." diff --git a/tests/cases/issues/issue_258/cases_issue_258.py b/tests/cases/issues/issue_258/cases_issue_258.py index 4aad3264..94aae46c 100644 --- a/tests/cases/issues/issue_258/cases_issue_258.py +++ b/tests/cases/issues/issue_258/cases_issue_258.py @@ -1,11 +1,12 @@ +# Import with AUTO from pytest_cases import case @case def case_1(): - return "hello world" + return "hello AUTO" @case def case_2(): - return "hello mars" + return "hi AUTO" diff --git a/tests/cases/issues/issue_258/cases_other.py b/tests/cases/issues/issue_258/cases_other.py new file mode 100644 index 00000000..9459361f --- /dev/null +++ b/tests/cases/issues/issue_258/cases_other.py @@ -0,0 +1,13 @@ +# Used by passing the corresponding module `test_other` to `get_all_cases` +# `get_all_cases(test_other)` +from pytest_cases import case + + +@case +def case_1(): + return "hello cases_other" + + +@case +def case_2(): + return "hi cases_other" diff --git a/tests/cases/issues/issue_258/test_issue_258.py b/tests/cases/issues/issue_258/test_issue_258.py index 2edae570..bb1fa37b 100644 --- a/tests/cases/issues/issue_258/test_issue_258.py +++ b/tests/cases/issues/issue_258/test_issue_258.py @@ -1,11 +1,7 @@ -from pytest_cases import get_all_cases, case, parametrize_with_cases, parametrize -import pytest -from pytest_cases.case_parametrizer_new import AUTO +from pytest_cases import (AUTO, case, get_all_cases, parametrize, + parametrize_with_cases) -# Test behaviour without a string module ref -############################################ - @case(tags=["a", "banana"]) def case_1(): return "a_banana" @@ -27,13 +23,13 @@ def case_4(): all_cases = get_all_cases(cases=[case_1, case_2, case_3, case_4]) - a_cases = get_all_cases(cases=all_cases, has_tag="a") b_cases = get_all_cases(cases=all_cases, has_tag="b") - banana_cases = get_all_cases(cases=a_cases + b_cases, has_tag=["banana"]) +# Test behaviour with explicit cases and no parametrization target +################################################################## @parametrize_with_cases("word", cases=all_cases) def test_all(word): assert word in ["a", "a_banana", "b", "b_banana"] @@ -54,26 +50,31 @@ def test_banana(word): assert "banana" in word -def test_get_cases_without_parametrization_target(): - assert len(list(all_cases)) == 4 - assert len(list(a_cases)) == 2 - assert len(list(b_cases)) == 2 - assert len(list(banana_cases)) == 2 - - -@parametrize("ref", ['.']) -def test_get_all_cases_raises_with_module_case(ref): - with pytest.raises(ValueError, match="Cases beginning with"): - get_all_cases(cases=ref) +# Test behaviour with string module ref and AUTO and no parametrization target +############################################################################## +def test_this_module_cases(): + this_module_cases = get_all_cases(cases=".") + assert set(this_module_cases) == {case_1, case_2, case_3, case_4} -# Test behaviour with string module ref -####################################### -def test_relative_import_cases_is_none_empty(): +def test_relative_module_cases(): relative_import_cases = get_all_cases(cases=".cases") - assert len(relative_import_cases) == 2 + assert {"hello .", "hi ."} == {f() for f in relative_import_cases} -def test_auto_import_cases_is_non_empty(): +def test_auto_cases(): auto_import_cases = get_all_cases(cases=AUTO) - assert len(auto_import_cases) == 2 + assert {"hello AUTO", "hi AUTO"} == {f() for f in auto_import_cases} + + +# Test behaviour with an explicit module parametrization target +############################################################### +from tests.cases.issues.issue_258 import test_other +def test_module_parametrization_auto(): + cases_other_cases = get_all_cases(test_other, cases=AUTO) + assert {"hello cases_other", "hi cases_other"} == {f() for f in cases_other_cases} + + +def test_module_parametrization_this_module(): + test_other_cases = get_all_cases(test_other, cases='.') + assert {"hello test_other", "hi test_other"} == {f() for f in test_other_cases} diff --git a/tests/cases/issues/issue_258/test_other.py b/tests/cases/issues/issue_258/test_other.py new file mode 100644 index 00000000..b7c1c206 --- /dev/null +++ b/tests/cases/issues/issue_258/test_other.py @@ -0,0 +1,11 @@ +from pytest_cases import case + + +@case +def case_1(): + return "hello test_other" + + +@case +def case_2(): + return "hi test_other"