From d97473e551ef70831c601f9c46f55ef030bb646f Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 28 Feb 2019 20:59:37 -0300 Subject: [PATCH] Add test and CHANGELOG for #1895 --- changelog/1895.bugfix.rst | 2 ++ testing/python/fixtures.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 changelog/1895.bugfix.rst diff --git a/changelog/1895.bugfix.rst b/changelog/1895.bugfix.rst new file mode 100644 index 000000000..44b921ad9 --- /dev/null +++ b/changelog/1895.bugfix.rst @@ -0,0 +1,2 @@ +Fix bug where fixtures requested dynamically via ``request.getfixturevalue()`` might be teardown +before the requesting fixture. diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index d9a512d70..45c7a17ae 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -562,6 +562,44 @@ class TestRequestBasic(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + def test_getfixturevalue_teardown(self, testdir): + """ + Issue #1895 + + `test_inner` requests `inner` fixture, which in turns requests `resource` + using getfixturevalue. `test_func` then requests `resource`. + + `resource` is teardown before `inner` because the fixture mechanism won't consider + `inner` dependent on `resource` when it is get via `getfixturevalue`: `test_func` + will then cause the `resource`'s finalizer to be called first because of this. + """ + testdir.makepyfile( + """ + import pytest + + @pytest.fixture(scope='session') + def resource(): + r = ['value'] + yield r + r.pop() + + @pytest.fixture(scope='session') + def inner(request): + resource = request.getfixturevalue('resource') + assert resource == ['value'] + yield + assert resource == ['value'] + + def test_inner(inner): + pass + + def test_func(resource): + pass + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines("* 2 passed in *") + @pytest.mark.parametrize("getfixmethod", ("getfixturevalue", "getfuncargvalue")) def test_getfixturevalue(self, testdir, getfixmethod): item = testdir.getitem(