Skip to content

Commit 4e59455

Browse files
authored
Merge pull request #5798 from aklajnert/570-indirect-fixtures
Fix the scope behavior with indirect fixtures
2 parents 01082fe + 35b3b10 commit 4e59455

File tree

4 files changed

+62
-3
lines changed

4 files changed

+62
-3
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Andras Tim
2323
Andrea Cimatoribus
2424
Andreas Zeidler
2525
Andrey Paramonov
26+
Andrzej Klajnert
2627
Andrzej Ostrowski
2728
Andy Freeland
2829
Anthon van der Neut

changelog/570.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed long standing issue where fixture scope was not respected when indirect fixtures were used during
2+
parametrization.

src/_pytest/fixtures.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ def execute(self, request):
859859
if argname != "request":
860860
fixturedef.addfinalizer(functools.partial(self.finish, request=request))
861861

862-
my_cache_key = request.param_index
862+
my_cache_key = self.cache_key(request)
863863
cached_result = getattr(self, "cached_result", None)
864864
if cached_result is not None:
865865
result, cache_key, err = cached_result
@@ -877,6 +877,9 @@ def execute(self, request):
877877
hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
878878
return hook.pytest_fixture_setup(fixturedef=self, request=request)
879879

880+
def cache_key(self, request):
881+
return request.param_index if not hasattr(request, "param") else request.param
882+
880883
def __repr__(self):
881884
return "<FixtureDef argname={!r} scope={!r} baseid={!r}>".format(
882885
self.argname, self.scope, self.baseid
@@ -913,7 +916,7 @@ def pytest_fixture_setup(fixturedef, request):
913916
kwargs[argname] = result
914917

915918
fixturefunc = resolve_fixture_function(fixturedef, request)
916-
my_cache_key = request.param_index
919+
my_cache_key = fixturedef.cache_key(request)
917920
try:
918921
result = call_fixture_func(fixturefunc, request, kwargs)
919922
except TEST_OUTCOME:

testing/python/fixtures.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,8 @@ def test_lookup_error(unknown):
449449
"*ERROR at setup of test_lookup_error*",
450450
" def test_lookup_error(unknown):*",
451451
"E fixture 'unknown' not found",
452-
"> available fixtures:*a_fixture,*b_fixture,*c_fixture,*d_fixture*monkeypatch,*", # sorted
452+
"> available fixtures:*a_fixture,*b_fixture,*c_fixture,*d_fixture*monkeypatch,*",
453+
# sorted
453454
"> use 'py*test --fixtures *' for help on them.",
454455
"*1 error*",
455456
]
@@ -4009,3 +4010,55 @@ def test_fixture_named_request(testdir):
40094010
" *test_fixture_named_request.py:5",
40104011
]
40114012
)
4013+
4014+
4015+
def test_indirect_fixture_does_not_break_scope(testdir):
4016+
"""Ensure that fixture scope is respected when using indirect fixtures (#570)"""
4017+
testdir.makepyfile(
4018+
"""
4019+
import pytest
4020+
4021+
instantiated = []
4022+
4023+
@pytest.fixture(scope="session")
4024+
def fixture_1(request):
4025+
instantiated.append(("fixture_1", request.param))
4026+
4027+
4028+
@pytest.fixture(scope="session")
4029+
def fixture_2(request):
4030+
instantiated.append(("fixture_2", request.param))
4031+
4032+
4033+
scenarios = [
4034+
("A", "a1"),
4035+
("A", "a2"),
4036+
("B", "b1"),
4037+
("B", "b2"),
4038+
("C", "c1"),
4039+
("C", "c2"),
4040+
]
4041+
4042+
@pytest.mark.parametrize(
4043+
"fixture_1,fixture_2", scenarios, indirect=["fixture_1", "fixture_2"]
4044+
)
4045+
def test_create_fixtures(fixture_1, fixture_2):
4046+
pass
4047+
4048+
4049+
def test_check_fixture_instantiations():
4050+
assert instantiated == [
4051+
('fixture_1', 'A'),
4052+
('fixture_2', 'a1'),
4053+
('fixture_2', 'a2'),
4054+
('fixture_1', 'B'),
4055+
('fixture_2', 'b1'),
4056+
('fixture_2', 'b2'),
4057+
('fixture_1', 'C'),
4058+
('fixture_2', 'c1'),
4059+
('fixture_2', 'c2'),
4060+
]
4061+
"""
4062+
)
4063+
result = testdir.runpytest()
4064+
result.assert_outcomes(passed=7)

0 commit comments

Comments
 (0)