pytest: Possible Bug in package scoped fixture teardown
Please consider the following diff against PyTest 4.1:
diff --git a/testing/python/fixture.py b/testing/python/fixture.py
index b6692ac9..7b59cef0 100644
--- a/testing/python/fixture.py
+++ b/testing/python/fixture.py
@@ -3792,7 +3792,11 @@ class TestScopeOrdering(object):
├── sub1
│ ├── __init__.py
│ ├── conftest.py
- │ └── test_1.py
+ │ ├── test_1.py
+ │ └── sub1_2
+ │ ├── __init__.py
+ │ ├── conftest.py
+ │ └── test_1_2.py
└── sub2
├── __init__.py
├── conftest.py
@@ -3824,6 +3828,30 @@ class TestScopeOrdering(object):
"""
)
)
+ sub1_2 = sub1.mkdir("sub1_2")
+ sub1_2.ensure("__init__.py")
+ sub1_2.join("conftest.py").write(
+ textwrap.dedent(
+ """\
+ import pytest
+ from ... import values
+ @pytest.fixture(scope="package")
+ def fix():
+ values.append("pre-sub1_2")
+ yield values
+ assert values.pop() == "pre-sub1_2"
+ """
+ )
+ )
+ sub1_2.join("test_1_2.py").write(
+ textwrap.dedent(
+ """\
+ from ... import values
+ def test_1_2(fix):
+ assert values == ["pre-sub1_2"]
+ """
+ )
+ )
sub2 = root.mkdir("sub2")
sub2.ensure("__init__.py")
sub2.join("conftest.py").write(
@@ -3849,7 +3877,103 @@ class TestScopeOrdering(object):
)
)
reprec = testdir.inline_run()
- reprec.assertoutcome(passed=2)
+ reprec.assertoutcome(passed=3)
+
+ def test_multiple_packages_inherit(self, testdir):
+ """Complex test involving multiple package fixtures. Make sure teardowns
+ are executed in order.
+ .
+ └── root
+ ├── __init__.py
+ ├── sub1
+ │ ├── __init__.py
+ │ ├── conftest.py
+ │ ├── test_1.py
+ │ └── sub1_2
+ │ ├── __init__.py
+ │ ├── conftest.py
+ │ └── test_1_2.py
+ └── sub2
+ ├── __init__.py
+ ├── conftest.py
+ └── test_2.py
+ """
+ root = testdir.mkdir("root")
+ root.join("__init__.py").write("values = []")
+ sub1 = root.mkdir("sub1")
+ sub1.ensure("__init__.py")
+ sub1.join("conftest.py").write(
+ textwrap.dedent(
+ """\
+ import pytest
+ from .. import values
+ @pytest.fixture(scope="package")
+ def fix():
+ values.append("pre-sub1")
+ yield values
+ assert values.pop() == "pre-sub1"
+ """
+ )
+ )
+ sub1.join("test_1.py").write(
+ textwrap.dedent(
+ """\
+ from .. import values
+ def test_1(fix):
+ assert values == ["pre-sub1"]
+ """
+ )
+ )
+ sub1_2 = sub1.mkdir("sub1_2")
+ sub1_2.ensure("__init__.py")
+ sub1_2.join("conftest.py").write(
+ textwrap.dedent(
+ """\
+ import pytest
+ from ... import values
+ @pytest.fixture(scope="package")
+ def fix(fix):
+ values.append("pre-sub1_2")
+ yield values
+ assert values.pop() == "pre-sub1_2"
+ """
+ )
+ )
+ sub1_2.join("test_1_2.py").write(
+ textwrap.dedent(
+ """\
+ from ... import values
+ def test_1_2(fix):
+ assert values == ["pre-sub1", "pre-sub1_2"]
+ """
+ )
+ )
+ sub2 = root.mkdir("sub2")
+ sub2.ensure("__init__.py")
+ sub2.join("conftest.py").write(
+ textwrap.dedent(
+ """\
+ import pytest
+ from .. import values
+ @pytest.fixture(scope="package")
+ def fix():
+ values.append("pre-sub2")
+ yield values
+ assert values.pop() == "pre-sub2"
+ """
+ )
+ )
+ sub2.join("test_2.py").write(
+ textwrap.dedent(
+ """\
+ from .. import values
+ def test_2(fix):
+ assert values == ["pre-sub2"]
+ """
+ )
+ )
+ reprec = testdir.inline_run()
+ reprec.assertoutcome(passed=3)
def test_call_fixture_function_error():
The difference in the tests is that on test_multiple_packages
, there’s no fixture reuse/extend, while on test_multiple_packages_inherit
I “extend” the fix
fixture.
On test_multiple_packages_inherit
, at teardown, I expect sub_1_2 to cleanup first, then sub_1, but the test fails at sub_2 because it still contains the item added in sub_1(which didn’t ran it’s teardown code yet?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 15 (11 by maintainers)
Currently we have the issue that multi level package scope is practically undefined and not safely fixable without major reworks
I haven’t tested the exact scenarios, but I believe this should be fixed with #11646. Please test
pip install pytest==8.0.0rc1
and let us know if not!