-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Package scoped fixture is evaluated multiple times if used in a sub-package #7256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This better demonstrates the wanted final behavior diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py
index 7fc87e387..162ae0298 100644
--- a/testing/python/fixtures.py
+++ b/testing/python/fixtures.py
@@ -1566,6 +1566,83 @@ class TestFixtureManagerParseFactories:
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2)
+ def test_package_fixture_complex_sub(self, testdir):
+ testdir.makepyfile(
+ __init__="""\
+ values = []
+ """
+ )
+ testdir.syspathinsert(testdir.tmpdir.dirname)
+ package = testdir.mkdir("package")
+ package.join("__init__.py").write("")
+ package.join("conftest.py").write(
+ textwrap.dedent(
+ """\
+ import pytest
+ from .. import values
+
+ @pytest.fixture(scope="session")
+ def zero():
+ try:
+ zero.__calls__ += 1
+ except AttributeError:
+ zero.__calls__ = 1
+ values.append("session")
+ yield values
+ values.pop()
+ assert zero.__calls__ == 1
+ assert one.__calls__ == 1
+ assert two.__calls__ == 1
+
+ @pytest.fixture(scope="package")
+ def one(zero):
+ try:
+ one.__calls__ += 1
+ except AttributeError:
+ one.__calls__ = 1
+ values.append("package")
+ yield values
+ values.pop()
+
+ @pytest.fixture(scope="package", autouse=True)
+ def two(zero):
+ try:
+ two.__calls__ += 1
+ except AttributeError:
+ two.__calls__ = 1
+ values.append("package-auto")
+ yield values
+ values.pop()
+ """
+ )
+ )
+ package.join("test_x.py").write(
+ textwrap.dedent(
+ """\
+ from .. import values
+ def test_package_autouse():
+ assert values == ["session", "package-auto"]
+ def test_package(one):
+ assert values == ["session", "package-auto", "package"]
+ """
+ )
+ )
+ sub1 = package.mkdir("sub1")
+ sub1.join("__init__.py").write("")
+ sub1.join("test_y.py").write(
+ textwrap.dedent(
+ """\
+ from ... import values
+ def test_package_autouse():
+ assert values == ["session", "package-auto"]
+ def test_package(one):
+ assert values == ["session", "package-auto", "package"]
+ """
+ )
+ )
+ reprec = testdir.inline_run()
+ reprec.assertoutcome(passed=4)
+
def test_collect_custom_items(self, testdir):
testdir.copy_example("fixtures/custom_item")
result = testdir.runpytest("foo") |
I've been digging into the source code and I can't seem to find my way around fixture scopes and their termination routines. Any guidance in the right direction? |
Thanks for the report @s0undt3ch, I will get a look into this at some point this week |
Thanks @symonk. |
Gentle ping @symonk. Got any updates? |
Is there a reference to the details about the intended behavior for this scope? I checked the docs but didn't see any specifics. My assumption is, based on the description in the docs, that it would tear down twice if the last test to run was My assumption based on the general idea, is that it would be allowed to run once per lowest package level and then teardown once for each lowest package level that it was run for. For example, if I had But this presents a problem, as another sub-package being introduced inside Another way I could see it implemented would be if it's only meant to apply to the package who's |
To me its straightforward, the behavior I'm after. |
But how would you attach the fixture the |
This is fixed by #11646. The test doesn't pass exactly, because once |
pip list
from the virtual environment you are usingWhen defining a package scoped fixture, if used in the package and in a sub-package, the fixture is evaluated twice.
Coinsider the following diff against PyTest 5.4.2 running on Linux:
pip list
The text was updated successfully, but these errors were encountered: