11""" discovery and running of std-library "unittest" style tests. """
2+ import functools
23import sys
34import traceback
45
@@ -107,6 +108,7 @@ class TestCaseFunction(Function):
107108 nofuncargs = True
108109 _excinfo = None
109110 _testcase = None
111+ _need_tearDown = None
110112
111113 def setup (self ):
112114 self ._testcase = self .parent .obj (self .name )
@@ -115,6 +117,8 @@ def setup(self):
115117 self ._request ._fillfixtures ()
116118
117119 def teardown (self ):
120+ if self ._need_tearDown :
121+ self ._testcase .tearDown ()
118122 self ._testcase = None
119123 self ._obj = None
120124
@@ -187,29 +191,44 @@ def addSuccess(self, testcase):
187191 def stopTest (self , testcase ):
188192 pass
189193
190- def _handle_skip (self ):
191- # implements the skipping machinery (see #2137)
192- # analog to pythons Lib/unittest/case.py:run
194+ def runtest (self ):
193195 testMethod = getattr (self ._testcase , self ._testcase ._testMethodName )
194- if getattr (self ._testcase .__class__ , "__unittest_skip__" , False ) or getattr (
195- testMethod , "__unittest_skip__" , False
196- ):
197- # If the class or method was skipped.
198- skip_why = getattr (
199- self ._testcase .__class__ , "__unittest_skip_why__" , ""
200- ) or getattr (testMethod , "__unittest_skip_why__" , "" )
201- self ._testcase ._addSkip (self , self ._testcase , skip_why )
202- return True
203- return False
204196
205- def runtest (self ):
206- if self .config .pluginmanager .get_plugin ("pdbinvoke" ) is None :
197+ class _GetOutOf_testPartExecutor (KeyboardInterrupt ):
198+ """Helper exception to get out of unittests's testPartExecutor."""
199+
200+ unittest = sys .modules .get ("unittest" )
201+ reraise = (KeyboardInterrupt , SystemExit , unittest .SkipTest )
202+ if unittest :
203+ reraise += (unittest .SkipTest ,)
204+
205+ @functools .wraps (testMethod )
206+ def wrapped_testMethod (* args , ** kwargs ):
207+ try :
208+ self .ihook .pytest_pyfunc_call (pyfuncitem = self )
209+ except reraise :
210+ raise
211+ except BaseException as exc :
212+ expecting_failure_method = getattr (
213+ testMethod , "__unittest_expecting_failure__" , False
214+ )
215+ expecting_failure_class = getattr (
216+ self , "__unittest_expecting_failure__" , False
217+ )
218+ expecting_failure = expecting_failure_class or expecting_failure_method
219+ self ._need_tearDown = True
220+
221+ if expecting_failure :
222+ raise
223+
224+ raise _GetOutOf_testPartExecutor (exc )
225+
226+ self ._testcase ._wrapped_testMethod = wrapped_testMethod
227+ self ._testcase ._testMethodName = "_wrapped_testMethod"
228+ try :
207229 self ._testcase (result = self )
208- else :
209- # disables tearDown and cleanups for post mortem debugging (see #1890)
210- if self ._handle_skip ():
211- return
212- self ._testcase .debug ()
230+ except _GetOutOf_testPartExecutor as exc :
231+ raise exc .args [0 ] from exc .args [0 ]
213232
214233 def _prunetraceback (self , excinfo ):
215234 Function ._prunetraceback (self , excinfo )
0 commit comments