summaryrefslogtreecommitdiff
path: root/src/_pytest/unittest.py
diff options
context:
space:
mode:
authorBruno Oliveira <nicoddemus@gmail.com>2018-10-06 20:30:18 -0300
committerBruno Oliveira <nicoddemus@gmail.com>2019-01-10 12:10:04 -0200
commit0f918b1a9dd14a2d046d19be6ec239e8e2df4cb2 (patch)
tree4bea7d16e1cee29c0eb6ac0ce5ddffa48f5985e5 /src/_pytest/unittest.py
parent0da5531c7c3c40386d7b268ab070ffd0f97bd52c (diff)
downloadpytest-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.py64
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