pytest-dev / pytest-dev/pytest
Parametrization with Variables Unexpectedly Changes Fixture Scope from Class-Level to Function-Level
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
I have a setup fixture that I've parameterized with class-level scope. When I directly specify the argument values as [("chrome", "windows", "latest")], it works fine, maintaining the class-level scope. However, when I try to use variables to set these argument values, I've noticed that the scope unexpectedly shifts to function-level.
tests/test_app.py
import pytest
@pytest.mark.usefixtures("setup")
class TestSmoke:
def test_1(self):
assert True
def test_2(self):
assert True
Scenario 1 with hardcoded values
tests/conftest.py
import pytest
def pytest_generate_tests(metafunc):
if 'setup' in metafunc.fixturenames:
metafunc.parametrize("setup",argvalues=[("chrome", "windows", "latest")], indirect=True, scope='class')
@pytest.fixture
def setup(request):
print(f"\nSetting up")
print(f"Param {request.param}")
print(f"fixture (scope={request.scope})")
yield
print(f"\nTearing down")
Output
python -m pytest -s -v -k "TestSmoke" tests
======================================================================================================= test session starts =======================================================================================================
platform darwin -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0 -- /Volumes/T7/mywork/pythonProject/dynamic_parameter/venv/bin/python
cachedir: .pytest_cache
rootdir: /Volumes/T7/mywork/pythonProject/dynamic_parameter
collected 2 items
tests/test_app.py::TestSmoke::test_1[setup0]
Setting up
Param ('chrome', 'windows', 'latest')
fixture (scope=class)
PASSED
tests/test_app.py::TestSmoke::test_2[setup0] PASSED
Tearing down
Scenario 2 with variable values
tests/conftest.py
import pytest
def pytest_generate_tests(metafunc):
browser_name = "chrome"
os_name = "windows"
browser_version = "latest"
if 'setup' in metafunc.fixturenames:
metafunc.parametrize("setup", argvalues=[(os_name, browser_name, browser_version)], indirect=True, scope='class')
@pytest.fixture
def setup(request):
print(f"\nSetting up")
print(f"Param {request.param}")
yield
print(f"\nTearing down")
Output
python -m pytest -s -v -k "TestSmoke" tests
======================================================================================================= test session starts =======================================================================================================
platform darwin -- Python 3.12.2, pytest-7.4.4, pluggy-1.4.0 -- /Volumes/T7/mywork/pythonProject/dynamic_parameter/venv/bin/python
cachedir: .pytest_cache
rootdir: /Volumes/T7/mywork/pythonProject/dynamic_parameter
collected 2 items
tests/test_app.py::TestSmoke::test_1[setup0]
Setting up
Param ('windows', 'chrome', 'latest')
PASSED
tests/test_app.py::TestSmoke::test_2[setup0]
Tearing down
Setting up
Param ('windows', 'chrome', 'latest')
PASSED
Tearing down
(venv) yogen@Mac-mini dynamic_parameter % pip list
Package Version
-------------- -------
attrs 23.2.0
iniconfig 2.0.0
more-itertools 10.2.0
packaging 24.0
pip 24.0
pluggy 1.4.0
py 1.11.0
pytest 8.1.1
toml 0.10.2
wcwidth 0.2.13
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the behavior using tests/conftest.py and tests/test_app.py with both hardcoded and variable parameter values. Then trace pytest's indirect parametrization and fixture-scope handling, and add a regression test showing that variable values retain class-level scope; done means setup runs once for both class tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100