python-pytest-cases
python-pytest-cases copied to clipboard
Fixture created for parametrized case not visible to test function in different module
As discussed in #158 (in particular https://github.com/smarie/python-pytest-cases/issues/158#issuecomment-747710915 and https://github.com/smarie/python-pytest-cases/issues/158#issuecomment-747942419), when a fixture is created for a parametrized case, if that case is used in a test that lies in a separate module, the fixture won't be visible and test collection will fail.
Related to #170, #169
Example
In the file test_foo_cases.py
:
import pytest_cases
class XCases:
@staticmethod
def case_foo():
return 1
class YCases:
@staticmethod
@pytest_cases.parametrize_with_cases("x", XCases.case_foo)
def case_foo(x):
return x
class ZCases:
@staticmethod
@pytest_cases.parametrize_with_cases("y", YCases.case_foo)
def case_foo(y):
return y
In test_foo.py
:
import pytest_cases
import test_foo_cases
@pytest_cases.parametrize_with_cases("y", test_foo_cases.ZCases.case_foo)
def test_foo(y):
pass
Trying to run test_foo
will result in an error during collection:
_______________________ ERROR at setup of test_foo[foo] _______________________
file .../test_foo.py, line 5: source code not available
file <makefun-gen-14>, line 1: source code not available
file ...
E fixture 'case_foo_y' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, foo, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, test_foo_y, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
Workarounds
Possible workarounds are:
- Import everything from the cases module to ensure all dynamically generated fixtures are visible in the test module too:
from test_foo_cases import *
- Selectively import the dynamically generated fixture in the test module:
case_foo_y = test_foo_cases.case_foo_y
. This relies on knowing the name of the generated fixture.
Possible solutions
- Dynamically add the fixture to all modules that reference the case too?
- Instead of adding the fixture to the cases module, add it to the closest
conftest.py
available?
Nice workaround from test_foo_cases import *
! I did not think it would work but actually there is no reason it shouldnt
Another possible solution is : stop creating hidden fixtures in @parametrize
(#170). A bit ambitious/challenging but not impossible.