Skip to content

Commit 2e04907

Browse files
Anton3bluetech
authored andcommitted
testing: add an xfail test demonstrating pytest_fixture_post_finalizer called more than once
1 parent ced0a8d commit 2e04907

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

testing/python/fixtures.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,6 +4219,68 @@ def test_func(my_fixture):
42194219
)
42204220

42214221

4222+
def test_fixture_post_finalizer_called_once(pytester: Pytester) -> None:
4223+
"""Test that pytest_fixture_post_finalizer is called only once per fixture teardown.
4224+
4225+
When a fixture depends on multiple parametrized fixtures and all their parameters
4226+
change at the same time, the dependent fixture should be torn down only once,
4227+
and pytest_fixture_post_finalizer should be called only once for it.
4228+
"""
4229+
pytester.makeconftest(
4230+
"""
4231+
import pytest
4232+
4233+
finalizer_calls = []
4234+
4235+
def pytest_fixture_post_finalizer(fixturedef, request):
4236+
finalizer_calls.append(fixturedef.argname)
4237+
4238+
@pytest.fixture(autouse=True)
4239+
def check_finalizer_calls(request):
4240+
yield
4241+
# After each test, verify no duplicate finalizer calls.
4242+
if finalizer_calls:
4243+
assert len(finalizer_calls) == len(set(finalizer_calls)), (
4244+
f"Duplicate finalizer calls detected: {finalizer_calls}"
4245+
)
4246+
finalizer_calls.clear()
4247+
"""
4248+
)
4249+
pytester.makepyfile(
4250+
test_fixtures="""
4251+
import pytest
4252+
4253+
@pytest.fixture(scope="session")
4254+
def foo(request):
4255+
return request.param
4256+
4257+
@pytest.fixture(scope="session")
4258+
def bar(request):
4259+
return request.param
4260+
4261+
@pytest.fixture(scope="session")
4262+
def baz(foo, bar):
4263+
return f"{foo}-{bar}"
4264+
4265+
@pytest.mark.parametrize("foo,bar", [(1, 1)], indirect=True)
4266+
def test_first(foo, bar, baz):
4267+
assert foo == 1
4268+
assert bar == 1
4269+
assert baz == "1-1"
4270+
4271+
@pytest.mark.parametrize("foo,bar", [(2, 2)], indirect=True)
4272+
def test_second(foo, bar, baz):
4273+
assert foo == 2
4274+
assert bar == 2
4275+
assert baz == "2-2"
4276+
"""
4277+
)
4278+
result = pytester.runpytest("-v")
4279+
# The test passes, which means no duplicate finalizer calls were detected
4280+
# by the check_finalizer_calls autouse fixture.
4281+
result.assert_outcomes(passed=2)
4282+
4283+
42224284
class TestScopeOrdering:
42234285
"""Class of tests that ensure fixtures are ordered based on their scopes (#2405)"""
42244286

0 commit comments

Comments
 (0)