@@ -5069,3 +5069,132 @@ def test_method(self, /, fix):
50695069 )
50705070 result = pytester .runpytest ()
50715071 result .assert_outcomes (passed = 1 )
5072+
5073+
5074+ def test_fixture_closure_with_overrides (pytester : Pytester ) -> None :
5075+ """Test that an item's static fixture closure properly includes transitive
5076+ dependencies through overridden fixtures (#13773)."""
5077+ pytester .makeconftest (
5078+ """
5079+ import pytest
5080+
5081+ @pytest.fixture
5082+ def db(): pass
5083+
5084+ @pytest.fixture
5085+ def app(db): pass
5086+ """
5087+ )
5088+ pytester .makepyfile (
5089+ """
5090+ import pytest
5091+
5092+ # Overrides conftest-level `app` and requests it.
5093+ @pytest.fixture
5094+ def app(app): pass
5095+
5096+ class TestClass:
5097+ # Overrides module-level `app` and requests it.
5098+ @pytest.fixture
5099+ def app(self, app): pass
5100+
5101+ def test_something(self, request, app):
5102+ # Both dynamic and static fixture closures should include 'db'.
5103+ assert 'db' in request.fixturenames
5104+ assert 'db' in request.node.fixturenames
5105+ # No dynamic dependencies, should be equal.
5106+ assert set(request.fixturenames) == set(request.node.fixturenames)
5107+ """
5108+ )
5109+ result = pytester .runpytest ("-v" )
5110+ result .assert_outcomes (passed = 1 )
5111+
5112+
5113+ @pytest .mark .xfail (reason = "not currently handled correctly" )
5114+ def test_fixture_closure_with_overrides_and_intermediary (pytester : Pytester ) -> None :
5115+ """Test that an item's static fixture closure properly includes transitive
5116+ dependencies through overridden fixtures (#13773).
5117+
5118+ A more complicated case than test_fixture_closure_with_overrides, adds an
5119+ intermediary so the override chain is not direct.
5120+ """
5121+ pytester .makeconftest (
5122+ """
5123+ import pytest
5124+
5125+ @pytest.fixture
5126+ def db(): pass
5127+
5128+ @pytest.fixture
5129+ def app(db): pass
5130+
5131+ @pytest.fixture
5132+ def intermediate(app): pass
5133+ """
5134+ )
5135+ pytester .makepyfile (
5136+ """
5137+ import pytest
5138+
5139+ # Overrides conftest-level `app` and requests it.
5140+ @pytest.fixture
5141+ def app(intermediate): pass
5142+
5143+ class TestClass:
5144+ # Overrides module-level `app` and requests it.
5145+ @pytest.fixture
5146+ def app(self, app): pass
5147+
5148+ def test_something(self, request, app):
5149+ # Both dynamic and static fixture closures should include 'db'.
5150+ assert 'db' in request.fixturenames
5151+ assert 'db' in request.node.fixturenames
5152+ # No dynamic dependencies, should be equal.
5153+ assert set(request.fixturenames) == set(request.node.fixturenames)
5154+ """
5155+ )
5156+ result = pytester .runpytest ("-v" )
5157+ result .assert_outcomes (passed = 1 )
5158+
5159+
5160+ def test_fixture_closure_with_broken_override_chain (pytester : Pytester ) -> None :
5161+ """Test that an item's static fixture closure properly includes transitive
5162+ dependencies through overridden fixtures (#13773).
5163+
5164+ A more complicated case than test_fixture_closure_with_overrides, one of the
5165+ fixtures in the chain doesn't call its super, so it shouldn't be included.
5166+ """
5167+ pytester .makeconftest (
5168+ """
5169+ import pytest
5170+
5171+ @pytest.fixture
5172+ def db(): pass
5173+
5174+ @pytest.fixture
5175+ def app(db): pass
5176+ """
5177+ )
5178+ pytester .makepyfile (
5179+ """
5180+ import pytest
5181+
5182+ # Overrides conftest-level `app` and *doesn't* request it.
5183+ @pytest.fixture
5184+ def app(): pass
5185+
5186+ class TestClass:
5187+ # Overrides module-level `app` and requests it.
5188+ @pytest.fixture
5189+ def app(self, app): pass
5190+
5191+ def test_something(self, request, app):
5192+ # Both dynamic and static fixture closures should include 'db'.
5193+ assert 'db' not in request.fixturenames
5194+ assert 'db' not in request.node.fixturenames
5195+ # No dynamic dependencies, should be equal.
5196+ assert set(request.fixturenames) == set(request.node.fixturenames)
5197+ """
5198+ )
5199+ result = pytester .runpytest ("-v" )
5200+ result .assert_outcomes (passed = 1 )
0 commit comments