Merge branch 'main' into teardown_fixture_order
This commit is contained in:
commit
74e094127a
|
@ -4624,10 +4624,85 @@ def test_staticmethod_classmethod_fixture_instance(pytester: Pytester) -> None:
|
||||||
result.assert_outcomes(passed=3)
|
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
|
||||||
|
|
||||||
|
|
||||||
def test_scoped_fixture_teardown_order(pytester: Pytester) -> None:
|
def test_scoped_fixture_teardown_order(pytester: Pytester) -> None:
|
||||||
"""
|
"""
|
||||||
Make sure teardowns happen in reverse order of setup with scoped fixtures, when
|
Make sure teardowns happen in reverse order of setup with scoped fixtures, when
|
||||||
a later test only depends on a subset of scoped fixtures.
|
a later test only depends on a subset of scoped fixtures.
|
||||||
|
|
||||||
Regression test for https://github.com/pytest-dev/pytest/issues/1489
|
Regression test for https://github.com/pytest-dev/pytest/issues/1489
|
||||||
"""
|
"""
|
||||||
pytester.makepyfile(
|
pytester.makepyfile(
|
||||||
|
@ -4644,30 +4719,30 @@ def test_scoped_fixture_teardown_order(pytester: Pytester) -> None:
|
||||||
def fixture_1() -> Generator[None, None, None]:
|
def fixture_1() -> Generator[None, None, None]:
|
||||||
global last_executed
|
global last_executed
|
||||||
assert last_executed == ""
|
assert last_executed == ""
|
||||||
last_executed = "autouse_setup"
|
last_executed = "fixture_1_setup"
|
||||||
yield
|
yield
|
||||||
assert last_executed == "noautouse_teardown"
|
assert last_executed == "fixture_2_teardown"
|
||||||
last_executed = "autouse_teardown"
|
last_executed = "fixture_1_teardown"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def fixture_2() -> Generator[None, None, None]:
|
def fixture_2() -> Generator[None, None, None]:
|
||||||
global last_executed
|
global last_executed
|
||||||
assert last_executed == "autouse_setup"
|
assert last_executed == "fixture_1_setup"
|
||||||
last_executed = "noautouse_setup"
|
last_executed = "fixture_2_setup"
|
||||||
yield
|
yield
|
||||||
assert last_executed == "run_test"
|
assert last_executed == "run_test"
|
||||||
last_executed = "noautouse_teardown"
|
last_executed = "fixture_2_teardown"
|
||||||
|
|
||||||
|
|
||||||
def test_autouse_fixture_teardown_order(fixture_1: None, fixture_2: None) -> None:
|
def test_fixture_teardown_order(fixture_1: None, fixture_2: None) -> None:
|
||||||
global last_executed
|
global last_executed
|
||||||
assert last_executed == "noautouse_setup"
|
assert last_executed == "fixture_2_setup"
|
||||||
last_executed = "run_test"
|
last_executed = "run_test"
|
||||||
|
|
||||||
|
|
||||||
def test_2(fixture_1: None) -> None:
|
def test_2(fixture_1: None) -> None:
|
||||||
# this would previously queue an additional teardown of fixture_1,
|
# This would previously queue an additional teardown of fixture_1,
|
||||||
# despite fixture_1's value being cached, which caused fixture_1 to be
|
# despite fixture_1's value being cached, which caused fixture_1 to be
|
||||||
# torn down before fixture_2 - violating the rule that teardowns should
|
# torn down before fixture_2 - violating the rule that teardowns should
|
||||||
# happen in reverse order of setup.
|
# happen in reverse order of setup.
|
||||||
|
@ -4675,4 +4750,4 @@ def test_scoped_fixture_teardown_order(pytester: Pytester) -> None:
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = pytester.runpytest()
|
result = pytester.runpytest()
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
Loading…
Reference in New Issue