mirror of https://github.com/python/cpython
Issue 8948. cleanup functions are not run by unittest.TestCase.debug(), plus class and module teardowns are not run by unittest.TestSuite.debug().
This commit is contained in:
parent
d7afd31a9b
commit
0fedb28951
|
@ -380,6 +380,9 @@ class TestCase(object):
|
|||
self.setUp()
|
||||
getattr(self, self._testMethodName)()
|
||||
self.tearDown()
|
||||
while self._cleanups:
|
||||
function, args, kwargs = self._cleanups.pop(-1)
|
||||
function(*args, **kwargs)
|
||||
|
||||
def skipTest(self, reason):
|
||||
"""Skip this test."""
|
||||
|
|
|
@ -87,9 +87,16 @@ class TestSuite(BaseTestSuite):
|
|||
self._handleModuleTearDown(result)
|
||||
return result
|
||||
|
||||
def debug(self):
|
||||
"""Run the tests without collecting errors in a TestResult"""
|
||||
debug = _DebugResult()
|
||||
self._wrapped_run(debug, True)
|
||||
self._tearDownPreviousClass(None, debug)
|
||||
self._handleModuleTearDown(debug)
|
||||
|
||||
################################
|
||||
# private methods
|
||||
def _wrapped_run(self, result):
|
||||
def _wrapped_run(self, result, debug=False):
|
||||
for test in self:
|
||||
if result.shouldStop:
|
||||
break
|
||||
|
@ -106,8 +113,10 @@ class TestSuite(BaseTestSuite):
|
|||
|
||||
if hasattr(test, '_wrapped_run'):
|
||||
test._wrapped_run(result)
|
||||
else:
|
||||
elif not debug:
|
||||
test(result)
|
||||
else:
|
||||
test.debug()
|
||||
|
||||
def _handleClassSetUp(self, test, result):
|
||||
previousClass = getattr(result, '_previousTestClass', None)
|
||||
|
@ -131,6 +140,8 @@ class TestSuite(BaseTestSuite):
|
|||
try:
|
||||
setUpClass()
|
||||
except Exception as e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
currentClass._classSetupFailed = True
|
||||
className = util.strclass(currentClass)
|
||||
errorName = 'setUpClass (%s)' % className
|
||||
|
@ -163,6 +174,8 @@ class TestSuite(BaseTestSuite):
|
|||
try:
|
||||
setUpModule()
|
||||
except Exception, e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
result._moduleSetUpFailed = True
|
||||
errorName = 'setUpModule (%s)' % currentModule
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
|
@ -192,6 +205,8 @@ class TestSuite(BaseTestSuite):
|
|||
try:
|
||||
tearDownModule()
|
||||
except Exception as e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
errorName = 'tearDownModule (%s)' % previousModule
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
|
||||
|
@ -212,6 +227,8 @@ class TestSuite(BaseTestSuite):
|
|||
try:
|
||||
tearDownClass()
|
||||
except Exception, e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
className = util.strclass(previousClass)
|
||||
errorName = 'tearDownClass (%s)' % className
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
|
@ -262,3 +279,10 @@ def _isnotsuite(test):
|
|||
except TypeError:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _DebugResult(object):
|
||||
"Used by the TestSuite to hold previous class when running in debug."
|
||||
_previousTestClass = None
|
||||
_moduleSetUpFailed = False
|
||||
shouldStop = False
|
||||
|
|
|
@ -111,6 +111,31 @@ class TestCleanUp(unittest.TestCase):
|
|||
test.run(result)
|
||||
self.assertEqual(ordering, ['setUp', 'cleanup1'])
|
||||
|
||||
def testTestCaseDebugExecutesCleanups(self):
|
||||
ordering = []
|
||||
|
||||
class TestableTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
ordering.append('setUp')
|
||||
self.addCleanup(cleanup1)
|
||||
|
||||
def testNothing(self):
|
||||
ordering.append('test')
|
||||
|
||||
def tearDown(self):
|
||||
ordering.append('tearDown')
|
||||
|
||||
test = TestableTest('testNothing')
|
||||
|
||||
def cleanup1():
|
||||
ordering.append('cleanup1')
|
||||
test.addCleanup(cleanup2)
|
||||
def cleanup2():
|
||||
ordering.append('cleanup2')
|
||||
|
||||
test.debug()
|
||||
self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2'])
|
||||
|
||||
|
||||
class Test_TextTestRunner(unittest.TestCase):
|
||||
"""Tests for TextTestRunner."""
|
||||
|
|
|
@ -439,6 +439,68 @@ class TestSetups(unittest.TestCase):
|
|||
skipped = result.skipped[0][0]
|
||||
self.assertEqual(str(skipped), 'setUpModule (Module)')
|
||||
|
||||
def test_suite_debug_executes_setups_and_teardowns(self):
|
||||
ordering = []
|
||||
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
ordering.append('setUpModule')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
ordering.append('tearDownModule')
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
ordering.append('setUpClass')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
ordering.append('tearDownClass')
|
||||
def test_something(self):
|
||||
ordering.append('test_something')
|
||||
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
|
||||
suite.debug()
|
||||
expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule']
|
||||
self.assertEqual(ordering, expectedOrder)
|
||||
|
||||
def test_suite_debug_propagates_exceptions(self):
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
if phase == 0:
|
||||
raise Exception('setUpModule')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
if phase == 1:
|
||||
raise Exception('tearDownModule')
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if phase == 2:
|
||||
raise Exception('setUpClass')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
if phase == 3:
|
||||
raise Exception('tearDownClass')
|
||||
def test_something(self):
|
||||
if phase == 4:
|
||||
raise Exception('test_something')
|
||||
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
|
||||
|
||||
messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something')
|
||||
for phase, msg in enumerate(messages):
|
||||
with self.assertRaisesRegexp(Exception, msg):
|
||||
suite.debug()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue