From bec0e9caf83616a4cd6494c6efed5cb5ba5f406d Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Fri, 15 Mar 2024 12:26:28 +0100
Subject: [PATCH] Add tests to ensure setup&finalization for scoped fixtures
only run once.
---
testing/python/fixtures.py | 74 ++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py
index 2e277626c..6051ab18f 100644
--- a/testing/python/fixtures.py
+++ b/testing/python/fixtures.py
@@ -4622,3 +4622,77 @@ def test_staticmethod_classmethod_fixture_instance(pytester: Pytester) -> None:
result = pytester.runpytest()
assert result.ret == ExitCode.OK
result.assert_outcomes(passed=3)
+
+
+def test_scoped_fixture_caching(pytester: Pytester) -> None:
+ """Make sure setup and finalization is only run once when using scoped fixture
+ multiple times."""
+ pytester.makepyfile(
+ """
+ from __future__ import annotations
+
+ from typing import Generator
+
+ import pytest
+ executed: list[str] = []
+ @pytest.fixture(scope="class")
+ def fixture_1() -> Generator[None, None, None]:
+ executed.append("fix setup")
+ yield
+ executed.append("fix teardown")
+
+
+ class TestFixtureCaching:
+ def test_1(self, fixture_1: None) -> None:
+ assert executed == ["fix setup"]
+
+ def test_2(self, fixture_1: None) -> None:
+ assert executed == ["fix setup"]
+
+
+ def test_expected_setup_and_teardown() -> None:
+ assert executed == ["fix setup", "fix teardown"]
+ """
+ )
+ result = pytester.runpytest()
+ assert result.ret == 0
+
+
+def test_scoped_fixture_caching_exception(pytester: Pytester) -> None:
+ """Make sure setup & finalization is only run once for scoped fixture, with a cached exception."""
+ pytester.makepyfile(
+ """
+ from __future__ import annotations
+
+ import pytest
+ executed_crash: list[str] = []
+
+
+ @pytest.fixture(scope="class")
+ def fixture_crash(request: pytest.FixtureRequest) -> None:
+ executed_crash.append("fix_crash setup")
+
+ def my_finalizer() -> None:
+ executed_crash.append("fix_crash teardown")
+
+ request.addfinalizer(my_finalizer)
+
+ raise Exception("foo")
+
+
+ class TestFixtureCachingException:
+ @pytest.mark.xfail
+ def test_crash_1(self, fixture_crash: None) -> None:
+ ...
+
+ @pytest.mark.xfail
+ def test_crash_2(self, fixture_crash: None) -> None:
+ ...
+
+
+ def test_crash_expected_setup_and_teardown() -> None:
+ assert executed_crash == ["fix_crash setup", "fix_crash teardown"]
+ """
+ )
+ result = pytester.runpytest()
+ assert result.ret == 0