diff options
author | Bruno Oliveira <nicoddemus@gmail.com> | 2018-10-06 20:30:18 -0300 |
---|---|---|
committer | Bruno Oliveira <nicoddemus@gmail.com> | 2019-01-10 12:10:04 -0200 |
commit | 0f918b1a9dd14a2d046d19be6ec239e8e2df4cb2 (patch) | |
tree | 4bea7d16e1cee29c0eb6ac0ce5ddffa48f5985e5 /src/_pytest/unittest.py | |
parent | 0da5531c7c3c40386d7b268ab070ffd0f97bd52c (diff) | |
download | pytest-0f918b1a9dd14a2d046d19be6ec239e8e2df4cb2.tar.gz |
xunit-style functions and methods are invoked by autouse fixtures
Fix #3094, Fix #517
Diffstat (limited to 'src/_pytest/unittest.py')
-rw-r--r-- | src/_pytest/unittest.py | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index 4a886c2e1..e00636d46 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -7,6 +7,7 @@ import sys import traceback import _pytest._code +import pytest from _pytest.compat import getimfunc from _pytest.config import hookimpl from _pytest.outcomes import fail @@ -32,24 +33,18 @@ class UnitTestCase(Class): # to declare that our children do not support funcargs nofuncargs = True - def setup(self): - cls = self.obj - if getattr(cls, "__unittest_skip__", False): - return # skipped - setup = getattr(cls, "setUpClass", None) - if setup is not None: - setup() - teardown = getattr(cls, "tearDownClass", None) - if teardown is not None: - self.addfinalizer(teardown) - super(UnitTestCase, self).setup() - def collect(self): from unittest import TestLoader cls = self.obj if not getattr(cls, "__test__", True): return + + skipped = getattr(cls, "__unittest_skip__", False) + if not skipped: + self._inject_setup_teardown_fixtures(cls) + self._inject_setup_class_fixture() + self.session._fixturemanager.parsefactories(self, unittest=True) loader = TestLoader() foundsomething = False @@ -68,6 +63,44 @@ class UnitTestCase(Class): if ut is None or runtest != ut.TestCase.runTest: yield TestCaseFunction("runTest", parent=self) + def _inject_setup_teardown_fixtures(self, cls): + """Injects a hidden auto-use fixture to invoke setUpClass/setup_method and corresponding + teardown functions (#517)""" + class_fixture = _make_xunit_fixture( + cls, "setUpClass", "tearDownClass", scope="class", pass_self=False + ) + if class_fixture: + cls.__pytest_class_setup = class_fixture + + method_fixture = _make_xunit_fixture( + cls, "setup_method", "teardown_method", scope="function", pass_self=True + ) + if method_fixture: + cls.__pytest_method_setup = method_fixture + + +def _make_xunit_fixture(obj, setup_name, teardown_name, scope, pass_self): + setup = getattr(obj, setup_name, None) + teardown = getattr(obj, teardown_name, None) + if setup is None and teardown is None: + return None + + @pytest.fixture(scope=scope, autouse=True) + def fixture(self, request): + if setup is not None: + if pass_self: + setup(self, request.function) + else: + setup() + yield + if teardown is not None: + if pass_self: + teardown(self, request.function) + else: + teardown() + + return fixture + class TestCaseFunction(Function): nofuncargs = True @@ -77,9 +110,6 @@ class TestCaseFunction(Function): def setup(self): self._testcase = self.parent.obj(self.name) self._fix_unittest_skip_decorator() - self._obj = getattr(self._testcase, self.name) - if hasattr(self._testcase, "setup_method"): - self._testcase.setup_method(self._obj) if hasattr(self, "_request"): self._request._fillfixtures() @@ -97,11 +127,7 @@ class TestCaseFunction(Function): setattr(self._testcase, "__name__", self.name) def teardown(self): - if hasattr(self._testcase, "teardown_method"): - self._testcase.teardown_method(self._obj) - # Allow garbage collection on TestCase instance attributes. self._testcase = None - self._obj = None def startTest(self, testcase): pass |