- [ x] a detailed description of the bug or suggestion
- [ x] output of
pip list from the virtual environment you are using
- [ x] pytest and operating system versions
- [ x] minimal example if possible
When setting up test parameterisation using a combination of pytest_generate_test hooks and fixture decorators, along with pytest.mark.parameterize decorators I'm seeing inconsistent behaviour with the fixtures which have scope='class'. In the application context these fixtures load large tables of data which takes quite a long time.
When an immutable object is passed as the fixture parameter - the fixtures behave as expected, however when mutable object, like a list is passed, the class fixture gets called repeatedly. The workaround identified in #896 did not seem to make a difference so I have opened a new issue.
If this is expected behaviour or a known bug I would like to add a warning to the docs to make this clear.
Possibly Related
#3678, #896
LSB Release
Distributor ID: Ubuntu
Description: Ubuntu 16.04.6 LTS
Release: 16.04
Codename: xenial
PIP Freeze >>
attrs==19.3.0
importlib-metadata==1.6.0
more-itertools==8.2.0
packaging==20.3
pluggy==0.13.1
py==1.8.1
pyparsing==2.4.7
pytest==5.4.1
six==1.14.0
wcwidth==0.1.9
zipp==3.1.0
Minimum Reproducible Example
import pytest
def pytest_generate_tests(metafunc):
if 'fixture_a' in metafunc.fixturenames:
metafunc.parametrize(
'fixture_a',
[1, ('a',), ['b']],
scope='class',
indirect=True,
)
@pytest.fixture(scope='session')
def fixture_a(request):
print('fixture_a CALLED')
return request.param
class TestExp:
@pytest.fixture(scope='class')
def fixture_d(self, fixture_a):
print('fixture_d CALLED')
return fixture_a
def test_func_one(self, fixture_d):
print(fixture_d)
@pytest.mark.parametrize(
'param_a',
['*', '+']
)
def test_func_two(self, fixture_d, param_a):
print(fixture_d, ' -> ', param_a)
Output of Test
platform linux -- Python 3.6.8, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- ...
cachedir: .pytest_cache
rootdir: ...
collected 9 items
test_mre.py::TestExp::test_func_one[1]
fixture_a CALLED
fixture_d CALLED
1
PASSED
test_mre.py::TestExp::test_func_two[1-*] 1 -> *
PASSED
test_mre.py::TestExp::test_func_two[1-+] 1 -> +
PASSED
test_mre.py::TestExp::test_func_one[fixture_a1]
fixture_a CALLED
fixture_d CALLED
('a',)
PASSED
test_mre.py::TestExp::test_func_two[fixture_a1-*] ('a',) -> *
PASSED
test_mre.py::TestExp::test_func_two[fixture_a1-+] ('a',) -> +
PASSED
test_mre.py::TestExp::test_func_one[fixture_a2]
fixture_a CALLED
fixture_d CALLED
['b']
PASSED
test_mre.py::TestExp::test_func_two[fixture_a2-*] <<< ---- Class scoped fixture called twice
fixture_a CALLED
fixture_d CALLED
['b'] -> *
PASSED
test_mre.py::TestExp::test_func_two[fixture_a2-+] ['b'] -> +
PASSED
pip listfrom the virtual environment you are usingWhen setting up test parameterisation using a combination of
pytest_generate_testhooks and fixture decorators, along withpytest.mark.parameterizedecorators I'm seeing inconsistent behaviour with the fixtures which havescope='class'. In the application context these fixtures load large tables of data which takes quite a long time.When an immutable object is passed as the fixture parameter - the fixtures behave as expected, however when mutable object, like a list is passed, the class fixture gets called repeatedly. The workaround identified in #896 did not seem to make a difference so I have opened a new issue.
If this is expected behaviour or a known bug I would like to add a warning to the docs to make this clear.
Possibly Related
#3678, #896
LSB Release
PIP Freeze >>
Minimum Reproducible Example
Output of Test