unittest: inline `_make_xunit_fixture`
The indirection makes things harder to follow in this case IMO.
This commit is contained in:
parent
c2a4a8d518
commit
a616adf3ae
|
@ -29,7 +29,6 @@ from _pytest.python import Class
|
||||||
from _pytest.python import Function
|
from _pytest.python import Function
|
||||||
from _pytest.python import Module
|
from _pytest.python import Module
|
||||||
from _pytest.runner import CallInfo
|
from _pytest.runner import CallInfo
|
||||||
from _pytest.scope import Scope
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -71,7 +70,8 @@ class UnitTestCase(Class):
|
||||||
|
|
||||||
skipped = _is_skipped(cls)
|
skipped = _is_skipped(cls)
|
||||||
if not skipped:
|
if not skipped:
|
||||||
self._inject_setup_teardown_fixtures(cls)
|
self._inject_unittest_setup_method_fixture(cls)
|
||||||
|
self._inject_unittest_setup_class_fixture(cls)
|
||||||
self._inject_setup_class_fixture()
|
self._inject_setup_class_fixture()
|
||||||
|
|
||||||
self.session._fixturemanager.parsefactories(self, unittest=True)
|
self.session._fixturemanager.parsefactories(self, unittest=True)
|
||||||
|
@ -93,91 +93,67 @@ class UnitTestCase(Class):
|
||||||
if ut is None or runtest != ut.TestCase.runTest: # type: ignore
|
if ut is None or runtest != ut.TestCase.runTest: # type: ignore
|
||||||
yield TestCaseFunction.from_parent(self, name="runTest")
|
yield TestCaseFunction.from_parent(self, name="runTest")
|
||||||
|
|
||||||
def _inject_setup_teardown_fixtures(self, cls: type) -> None:
|
def _inject_unittest_setup_class_fixture(self, cls: type) -> None:
|
||||||
"""Injects a hidden auto-use fixture to invoke setUpClass/setup_method and corresponding
|
"""Injects a hidden auto-use fixture to invoke setUpClass and
|
||||||
teardown functions (#517)."""
|
tearDownClass (#517)."""
|
||||||
class_fixture = _make_xunit_fixture(
|
setup = getattr(cls, "setUpClass", None)
|
||||||
cls,
|
teardown = getattr(cls, "tearDownClass", None)
|
||||||
"setUpClass",
|
if setup is None and teardown is None:
|
||||||
"tearDownClass",
|
return None
|
||||||
"doClassCleanups",
|
cleanup = getattr(cls, "doClassCleanups", lambda: None)
|
||||||
scope=Scope.Class,
|
|
||||||
pass_self=False,
|
@pytest.fixture(
|
||||||
|
scope="class",
|
||||||
|
autouse=True,
|
||||||
|
# Use a unique name to speed up lookup.
|
||||||
|
name=f"_unittest_setUpClass_fixture_{cls.__qualname__}",
|
||||||
)
|
)
|
||||||
if class_fixture:
|
def fixture(self) -> Generator[None, None, None]:
|
||||||
cls.__pytest_class_setup = class_fixture # type: ignore[attr-defined]
|
if _is_skipped(self):
|
||||||
|
reason = self.__unittest_skip_why__
|
||||||
method_fixture = _make_xunit_fixture(
|
raise pytest.skip.Exception(reason, _use_item_location=True)
|
||||||
cls,
|
if setup is not None:
|
||||||
"setup_method",
|
try:
|
||||||
"teardown_method",
|
|
||||||
None,
|
|
||||||
scope=Scope.Function,
|
|
||||||
pass_self=True,
|
|
||||||
)
|
|
||||||
if method_fixture:
|
|
||||||
cls.__pytest_method_setup = method_fixture # type: ignore[attr-defined]
|
|
||||||
|
|
||||||
|
|
||||||
def _make_xunit_fixture(
|
|
||||||
obj: type,
|
|
||||||
setup_name: str,
|
|
||||||
teardown_name: str,
|
|
||||||
cleanup_name: Optional[str],
|
|
||||||
scope: Scope,
|
|
||||||
pass_self: bool,
|
|
||||||
):
|
|
||||||
setup = getattr(obj, setup_name, None)
|
|
||||||
teardown = getattr(obj, teardown_name, None)
|
|
||||||
if setup is None and teardown is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if cleanup_name:
|
|
||||||
cleanup = getattr(obj, cleanup_name, lambda *args: None)
|
|
||||||
else:
|
|
||||||
|
|
||||||
def cleanup(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@pytest.fixture(
|
|
||||||
scope=scope.value,
|
|
||||||
autouse=True,
|
|
||||||
# Use a unique name to speed up lookup.
|
|
||||||
name=f"_unittest_{setup_name}_fixture_{obj.__qualname__}",
|
|
||||||
)
|
|
||||||
def fixture(self, request: FixtureRequest) -> Generator[None, None, None]:
|
|
||||||
if _is_skipped(self):
|
|
||||||
reason = self.__unittest_skip_why__
|
|
||||||
raise pytest.skip.Exception(reason, _use_item_location=True)
|
|
||||||
if setup is not None:
|
|
||||||
try:
|
|
||||||
if pass_self:
|
|
||||||
setup(self, request.function)
|
|
||||||
else:
|
|
||||||
setup()
|
setup()
|
||||||
# unittest does not call the cleanup function for every BaseException, so we
|
# unittest does not call the cleanup function for every BaseException, so we
|
||||||
# follow this here.
|
# follow this here.
|
||||||
except Exception:
|
except Exception:
|
||||||
if pass_self:
|
|
||||||
cleanup(self)
|
|
||||||
else:
|
|
||||||
cleanup()
|
cleanup()
|
||||||
|
raise
|
||||||
raise
|
yield
|
||||||
yield
|
try:
|
||||||
try:
|
if teardown is not None:
|
||||||
if teardown is not None:
|
|
||||||
if pass_self:
|
|
||||||
teardown(self, request.function)
|
|
||||||
else:
|
|
||||||
teardown()
|
teardown()
|
||||||
finally:
|
finally:
|
||||||
if pass_self:
|
|
||||||
cleanup(self)
|
|
||||||
else:
|
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|
||||||
return fixture
|
cls.__pytest_class_setup = fixture # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
def _inject_unittest_setup_method_fixture(self, cls: type) -> None:
|
||||||
|
"""Injects a hidden auto-use fixture to invoke setup_method and
|
||||||
|
teardown_method (#517)."""
|
||||||
|
setup = getattr(cls, "setup_method", None)
|
||||||
|
teardown = getattr(cls, "teardown_method", None)
|
||||||
|
if setup is None and teardown is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
scope="function",
|
||||||
|
autouse=True,
|
||||||
|
# Use a unique name to speed up lookup.
|
||||||
|
name=f"_unittest_setup_method_fixture_{cls.__qualname__}",
|
||||||
|
)
|
||||||
|
def fixture(self, request: FixtureRequest) -> Generator[None, None, None]:
|
||||||
|
if _is_skipped(self):
|
||||||
|
reason = self.__unittest_skip_why__
|
||||||
|
raise pytest.skip.Exception(reason, _use_item_location=True)
|
||||||
|
if setup is not None:
|
||||||
|
setup(self, request.function)
|
||||||
|
yield
|
||||||
|
if teardown is not None:
|
||||||
|
teardown(self, request.function)
|
||||||
|
|
||||||
|
cls.__pytest_method_setup = fixture # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
|
||||||
class TestCaseFunction(Function):
|
class TestCaseFunction(Function):
|
||||||
|
|
Loading…
Reference in New Issue