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()
|
self.setUp()
|
||||||
getattr(self, self._testMethodName)()
|
getattr(self, self._testMethodName)()
|
||||||
self.tearDown()
|
self.tearDown()
|
||||||
|
while self._cleanups:
|
||||||
|
function, args, kwargs = self._cleanups.pop(-1)
|
||||||
|
function(*args, **kwargs)
|
||||||
|
|
||||||
def skipTest(self, reason):
|
def skipTest(self, reason):
|
||||||
"""Skip this test."""
|
"""Skip this test."""
|
||||||
|
|
|
@ -87,9 +87,16 @@ class TestSuite(BaseTestSuite):
|
||||||
self._handleModuleTearDown(result)
|
self._handleModuleTearDown(result)
|
||||||
return 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
|
# private methods
|
||||||
def _wrapped_run(self, result):
|
def _wrapped_run(self, result, debug=False):
|
||||||
for test in self:
|
for test in self:
|
||||||
if result.shouldStop:
|
if result.shouldStop:
|
||||||
break
|
break
|
||||||
|
@ -106,8 +113,10 @@ class TestSuite(BaseTestSuite):
|
||||||
|
|
||||||
if hasattr(test, '_wrapped_run'):
|
if hasattr(test, '_wrapped_run'):
|
||||||
test._wrapped_run(result)
|
test._wrapped_run(result)
|
||||||
else:
|
elif not debug:
|
||||||
test(result)
|
test(result)
|
||||||
|
else:
|
||||||
|
test.debug()
|
||||||
|
|
||||||
def _handleClassSetUp(self, test, result):
|
def _handleClassSetUp(self, test, result):
|
||||||
previousClass = getattr(result, '_previousTestClass', None)
|
previousClass = getattr(result, '_previousTestClass', None)
|
||||||
|
@ -131,6 +140,8 @@ class TestSuite(BaseTestSuite):
|
||||||
try:
|
try:
|
||||||
setUpClass()
|
setUpClass()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if isinstance(result, _DebugResult):
|
||||||
|
raise
|
||||||
currentClass._classSetupFailed = True
|
currentClass._classSetupFailed = True
|
||||||
className = util.strclass(currentClass)
|
className = util.strclass(currentClass)
|
||||||
errorName = 'setUpClass (%s)' % className
|
errorName = 'setUpClass (%s)' % className
|
||||||
|
@ -163,6 +174,8 @@ class TestSuite(BaseTestSuite):
|
||||||
try:
|
try:
|
||||||
setUpModule()
|
setUpModule()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
if isinstance(result, _DebugResult):
|
||||||
|
raise
|
||||||
result._moduleSetUpFailed = True
|
result._moduleSetUpFailed = True
|
||||||
errorName = 'setUpModule (%s)' % currentModule
|
errorName = 'setUpModule (%s)' % currentModule
|
||||||
self._addClassOrModuleLevelException(result, e, errorName)
|
self._addClassOrModuleLevelException(result, e, errorName)
|
||||||
|
@ -192,6 +205,8 @@ class TestSuite(BaseTestSuite):
|
||||||
try:
|
try:
|
||||||
tearDownModule()
|
tearDownModule()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if isinstance(result, _DebugResult):
|
||||||
|
raise
|
||||||
errorName = 'tearDownModule (%s)' % previousModule
|
errorName = 'tearDownModule (%s)' % previousModule
|
||||||
self._addClassOrModuleLevelException(result, e, errorName)
|
self._addClassOrModuleLevelException(result, e, errorName)
|
||||||
|
|
||||||
|
@ -212,6 +227,8 @@ class TestSuite(BaseTestSuite):
|
||||||
try:
|
try:
|
||||||
tearDownClass()
|
tearDownClass()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
if isinstance(result, _DebugResult):
|
||||||
|
raise
|
||||||
className = util.strclass(previousClass)
|
className = util.strclass(previousClass)
|
||||||
errorName = 'tearDownClass (%s)' % className
|
errorName = 'tearDownClass (%s)' % className
|
||||||
self._addClassOrModuleLevelException(result, e, errorName)
|
self._addClassOrModuleLevelException(result, e, errorName)
|
||||||
|
@ -262,3 +279,10 @@ def _isnotsuite(test):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return True
|
return True
|
||||||
return False
|
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)
|
test.run(result)
|
||||||
self.assertEqual(ordering, ['setUp', 'cleanup1'])
|
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):
|
class Test_TextTestRunner(unittest.TestCase):
|
||||||
"""Tests for TextTestRunner."""
|
"""Tests for TextTestRunner."""
|
||||||
|
|
|
@ -439,6 +439,68 @@ class TestSetups(unittest.TestCase):
|
||||||
skipped = result.skipped[0][0]
|
skipped = result.skipped[0][0]
|
||||||
self.assertEqual(str(skipped), 'setUpModule (Module)')
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue