pytest-dev / pytest-dev/pytest
run class scoped parametrized fixture's dependency fixture's teardown after each test class iteration
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
Problem:
The conftest.py fixture's setup/teardown is not executed after each test class iteration.
When running pytest test_foo.py --setup-plan, the SETUP C conf_fixt is only executed before the first parametrized class iteration, and TEARDOWN C conf_fixt is only executed after the last parameterized class iteration is complete.
Related Files:
conftest.py
import pytest
from random import randint
@pytest.fixture(scope='class')
def conf_fixt():
y = randint(1, 100000)
yield y
print(f'teardown: {y}')
test_foo.py
from buildspecs.foo.conftest import conf_fixt
import pytest
@pytest.mark.parametrize("scenario", [
("scenario_1"),
("scenario_2")
], scope='class')
class TestZoo:
@pytest.fixture(scope="class")
def scenario_1(self):
yield 'scenario_1'
@pytest.fixture(scope="class")
def scenario_2(self):
yield 'scenario_2'
def test_scenario(self, scenario, request, conf_fixt):
print(f'scenario value: {request.getfixturevalue(scenario)}')
print(f'conf_fixt value: {conf_fixt}')
def test_other(self, scenario, request, conf_fixt):
print(f'scenario value: {request.getfixturevalue(scenario)}')
print(f'conf_fixt value: {conf_fixt}')
Actual:
pytest test_foo.py
platform linux -- Python 3.9.8, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /src
plugins: mock-3.6.1
collected 4 items
test_foo.py scenario value: scenario_1
conf_fixt value: 111111
.scenario value: scenario_1
conf_fixt value: 111111
.scenario value: scenario_2
conf_fixt value: 111111
.scenario value: scenario_2
conf_fixt value: 111111
.teardown: 111111
pytest test_foo.py --setup-plan
platform linux -- Python 3.9.8, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /src
plugins: mock-3.6.1
collected 2 items
test_foo.py
SETUP C conf_fixt
SETUP C scenario['scenario_1']
buildspecs/foo/test_foo.py::TestZoo::test_scenario[scenario_1] (fixtures used: conf_fixt, request, scenario)
TEARDOWN C scenario['scenario_1']
SETUP C scenario['scenario_2']
buildspecs/foo/test_foo.py::TestZoo::test_scenario[scenario_2] (fixtures used: conf_fixt, request, scenario)
TEARDOWN C scenario['scenario_2']
TEARDOWN C conf_fixt
Expected:
pytest test_foo.py
platform linux -- Python 3.9.8, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /src
plugins: mock-3.6.1
collected 4 items
test_foo.py scenario value: scenario_1
conf_fixt value: 111111
.scenario value: scenario_1
conf_fixt value: 111111
.teardown: 111111
.scenario value: scenario_2
conf_fixt value: 222222
.scenario value: scenario_2
conf_fixt value: 222222
.teardown: 222222
pytest test_foo.py --setup-plan
platform linux -- Python 3.9.8, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /src
plugins: mock-3.6.1
collected 2 items
test_foo.py
SETUP C conf_fixt
SETUP C scenario['scenario_1']
buildspecs/foo/test_foo.py::TestZoo::test_scenario[scenario_1] (fixtures used: conf_fixt, request, scenario)
TEARDOWN C scenario['scenario_1']
###Expected teardown
TEARDOWN C conf_fixt
###
SETUP C scenario['scenario_2']
buildspecs/foo/test_foo.py::TestZoo::test_scenario[scenario_2] (fixtures used: conf_fixt, request, scenario)
TEARDOWN C scenario['scenario_2']
TEARDOWN C conf_fixt
Attempts:
Add the conf_fixt fixture to the pytest.marks.parametrize() decorator like so:
import pytest
@pytest.mark.parametrize("scenario,conf_fixt_param", [
("scenario_1", "conf_fixt"),
("scenario_2", "conf_fixt")
], scope='class')
class TestZoo:
@pytest.fixture(scope="class")
def scenario_1(self):
yield 'scenario_1'
@pytest.fixture(scope="class")
def scenario_2(self):
yield 'scenario_2'
def test_scenario(self, scenario, request, conf_fixt_param):
print(f'scenario value: {request.getfixturevalue(scenario)}')
print(f'conf_fixt value: {request.getfixturevalue(conf_fixt_param)}')
def test_other(self, scenario, request, conf_fixt_param):
print(f'scenario value: {request.getfixturevalue(scenario)}')
print(f'conf_fixt value: {request.getfixturevalue(conf_fixt_param)}')
Same Actual and Expected output as the original problem.
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
Start by reproducing the class-scoped parametrization with the provided conftest.py and test_foo.py examples, including --setup-plan. Trace pytest's fixture setup and teardown ordering for each class parameter, then add a regression test covering the expected per-iteration teardown and verify that both the normal output and setup plan match the expected behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100