Feature Request: Ability to define fixtures in case file
Currently it seems that fixtures must be defined in test_foo.py, and defining a fixture in test_foo_cases.py does not work. It would be nice if fixtures defined in test_foo_cases.py could be used within the same file.
Motivation
If the test cases defined in test_foo_cases.py will use a fixture, being able to those fixtures in the same file would be good for organization (data locality).
Repro:
Currently the following does not work:
# test_foo.py
from pytest_cases import parametrize_with_cases
@parametrize_with_cases("test_case")
def test_simple(test_case):
assert test_case == 124
# test_foo_cases.py
from pytest_cases import fixture
@fixture
def fixt():
return 123
def case_simple(fixt):
return fixt + 1
This fails as follows:
$ pytest
================================================================== test session starts ==================================================================
platform linux -- Python 3.9.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /home/jbss/pysc/tensor_from_dom2
plugins: cov-2.12.1, hydra-core-1.1.1, cases-3.6.3
collected 1 item
test_foo.py E [100%]
======================================================================== ERRORS =========================================================================
_________________________________________________________ ERROR at setup of test_simple[simple] _________________________________________________________
file /home/jbss/pysc/tensor_from_dom2/test_foo.py, line 3: source code not available
file <makefun-gen-8>, line 1: source code not available
file <makefun-gen-6>, line 1: source code not available
E fixture 'fixt' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, cov, current_cases, doctest_namespace, hydra_restore_singletons, hydra_sweep_runner, hydra_task_runner, monkeypatch, no_cover, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, simple, symbol_id, test_simple_test_case, tick_size, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
<makefun-gen-6>:1
================================================================ short test summary info ================================================================
ERROR test_foo.py::test_simple[simple]
=================================================================== 1 error in 0.02s ====================================================================
Workaround
The fixture can be defined in test_foo.py or in conftest.py:
# test_foo.py
from pytest_cases import fixture, parametrize_with_cases
@fixture
def fixt():
return 123
@parametrize_with_cases("test_case")
def test_simple(test_case):
assert test_case == 124
# test_foo_cases.py
def case_simple(fixt):
return fixt + 1
$ pytest
...
=================================================================== 1 passed in 0.02s ===================================================================
This is documented in the Cases Requiring Fixtures section of the docs: "make sure the fixture exists or is imported either in the module where @parametrize_with_cases is used, or in a conftest.py file in one of the parent packages."
Possibly related to this issue: https://github.com/smarie/python-pytest-cases/issues/174
Thanks for the feedback @Jasha10 !
I think that the workaround for issue #174 should solve your issue as well, did you try ?
# test_foo.py
from pytest_cases import parametrize_with_cases
from .test_foo_cases import * # <-- this line does the trick
@parametrize_with_cases("test_case")
def test_simple(test_case):
assert test_case == 124
# test_foo_cases.py
from pytest_cases import fixture
@fixture
def fixt():
return 123
def case_simple(fixt):
return fixt + 1
did you try ?
I had not tried this. It works! Thanks for the tip :)
For those who use the from ... import * trick, make sure your fixture names do not start with an underscore!
According to the python docs, from pytest_cases import * "imports all names except those beginning with an underscore (_)."
Indeed, thanks for the trick @Jasha10 !