Skip to content

Commit d97473e

Browse files
committed
Add test and CHANGELOG for pytest-dev#1895
1 parent 525639e commit d97473e

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

changelog/1895.bugfix.rst

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix bug where fixtures requested dynamically via ``request.getfixturevalue()`` might be teardown
2+
before the requesting fixture.

testing/python/fixtures.py

+38
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,44 @@ def test_func(something):
562562
reprec = testdir.inline_run()
563563
reprec.assertoutcome(passed=1)
564564

565+
def test_getfixturevalue_teardown(self, testdir):
566+
"""
567+
Issue #1895
568+
569+
`test_inner` requests `inner` fixture, which in turns requests `resource`
570+
using getfixturevalue. `test_func` then requests `resource`.
571+
572+
`resource` is teardown before `inner` because the fixture mechanism won't consider
573+
`inner` dependent on `resource` when it is get via `getfixturevalue`: `test_func`
574+
will then cause the `resource`'s finalizer to be called first because of this.
575+
"""
576+
testdir.makepyfile(
577+
"""
578+
import pytest
579+
580+
@pytest.fixture(scope='session')
581+
def resource():
582+
r = ['value']
583+
yield r
584+
r.pop()
585+
586+
@pytest.fixture(scope='session')
587+
def inner(request):
588+
resource = request.getfixturevalue('resource')
589+
assert resource == ['value']
590+
yield
591+
assert resource == ['value']
592+
593+
def test_inner(inner):
594+
pass
595+
596+
def test_func(resource):
597+
pass
598+
"""
599+
)
600+
result = testdir.runpytest()
601+
result.stdout.fnmatch_lines("* 2 passed in *")
602+
565603
@pytest.mark.parametrize("getfixmethod", ("getfixturevalue", "getfuncargvalue"))
566604
def test_getfixturevalue(self, testdir, getfixmethod):
567605
item = testdir.getitem(

0 commit comments

Comments
 (0)