148 lines
6.3 KiB
Python
148 lines
6.3 KiB
Python
import unittest
|
|
from io import StringIO
|
|
from unittest import mock
|
|
from unittest.suite import _DebugResult
|
|
|
|
from django.test import SimpleTestCase
|
|
|
|
|
|
class ErrorTestCase(SimpleTestCase):
|
|
def raising_test(self):
|
|
self._pre_setup.assert_called_once_with()
|
|
raise Exception("debug() bubbles up exceptions before cleanup.")
|
|
|
|
def simple_test(self):
|
|
self._pre_setup.assert_called_once_with()
|
|
|
|
@unittest.skip("Skip condition.")
|
|
def skipped_test(self):
|
|
pass
|
|
|
|
|
|
@mock.patch.object(ErrorTestCase, "_post_teardown")
|
|
@mock.patch.object(ErrorTestCase, "_pre_setup")
|
|
class DebugInvocationTests(SimpleTestCase):
|
|
def get_runner(self):
|
|
return unittest.TextTestRunner(stream=StringIO())
|
|
|
|
def isolate_debug_test(self, test_suite, result):
|
|
# Suite teardown needs to be manually called to isolate failures.
|
|
test_suite._tearDownPreviousClass(None, result)
|
|
test_suite._handleModuleTearDown(result)
|
|
|
|
def test_run_cleanup(self, _pre_setup, _post_teardown):
|
|
"""Simple test run: catches errors and runs cleanup."""
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("raising_test"))
|
|
result = self.get_runner()._makeResult()
|
|
self.assertEqual(result.errors, [])
|
|
test_suite.run(result)
|
|
self.assertEqual(len(result.errors), 1)
|
|
_, traceback = result.errors[0]
|
|
self.assertIn(
|
|
"Exception: debug() bubbles up exceptions before cleanup.", traceback
|
|
)
|
|
_pre_setup.assert_called_once_with()
|
|
_post_teardown.assert_called_once_with()
|
|
|
|
def test_run_pre_setup_error(self, _pre_setup, _post_teardown):
|
|
_pre_setup.side_effect = Exception("Exception in _pre_setup.")
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("simple_test"))
|
|
result = self.get_runner()._makeResult()
|
|
self.assertEqual(result.errors, [])
|
|
test_suite.run(result)
|
|
self.assertEqual(len(result.errors), 1)
|
|
_, traceback = result.errors[0]
|
|
self.assertIn("Exception: Exception in _pre_setup.", traceback)
|
|
# pre-setup is called but not post-teardown.
|
|
_pre_setup.assert_called_once_with()
|
|
self.assertFalse(_post_teardown.called)
|
|
|
|
def test_run_post_teardown_error(self, _pre_setup, _post_teardown):
|
|
_post_teardown.side_effect = Exception("Exception in _post_teardown.")
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("simple_test"))
|
|
result = self.get_runner()._makeResult()
|
|
self.assertEqual(result.errors, [])
|
|
test_suite.run(result)
|
|
self.assertEqual(len(result.errors), 1)
|
|
_, traceback = result.errors[0]
|
|
self.assertIn("Exception: Exception in _post_teardown.", traceback)
|
|
# pre-setup and post-teardwn are called.
|
|
_pre_setup.assert_called_once_with()
|
|
_post_teardown.assert_called_once_with()
|
|
|
|
def test_run_skipped_test_no_cleanup(self, _pre_setup, _post_teardown):
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("skipped_test"))
|
|
try:
|
|
test_suite.run(self.get_runner()._makeResult())
|
|
except unittest.SkipTest:
|
|
self.fail("SkipTest should not be raised at this stage.")
|
|
self.assertFalse(_post_teardown.called)
|
|
self.assertFalse(_pre_setup.called)
|
|
|
|
def test_debug_cleanup(self, _pre_setup, _post_teardown):
|
|
"""Simple debug run without errors."""
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("simple_test"))
|
|
test_suite.debug()
|
|
_pre_setup.assert_called_once_with()
|
|
_post_teardown.assert_called_once_with()
|
|
|
|
def test_debug_bubbles_error(self, _pre_setup, _post_teardown):
|
|
"""debug() bubbles up exceptions before cleanup."""
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("raising_test"))
|
|
msg = "debug() bubbles up exceptions before cleanup."
|
|
with self.assertRaisesMessage(Exception, msg):
|
|
# This is the same as test_suite.debug().
|
|
result = _DebugResult()
|
|
test_suite.run(result, debug=True)
|
|
# pre-setup is called but not post-teardown.
|
|
_pre_setup.assert_called_once_with()
|
|
self.assertFalse(_post_teardown.called)
|
|
self.isolate_debug_test(test_suite, result)
|
|
|
|
def test_debug_bubbles_pre_setup_error(self, _pre_setup, _post_teardown):
|
|
"""debug() bubbles up exceptions during _pre_setup."""
|
|
msg = "Exception in _pre_setup."
|
|
_pre_setup.side_effect = Exception(msg)
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("simple_test"))
|
|
with self.assertRaisesMessage(Exception, msg):
|
|
# This is the same as test_suite.debug().
|
|
result = _DebugResult()
|
|
test_suite.run(result, debug=True)
|
|
# pre-setup is called but not post-teardown.
|
|
_pre_setup.assert_called_once_with()
|
|
self.assertFalse(_post_teardown.called)
|
|
self.isolate_debug_test(test_suite, result)
|
|
|
|
def test_debug_bubbles_post_teardown_error(self, _pre_setup, _post_teardown):
|
|
"""debug() bubbles up exceptions during _post_teardown."""
|
|
msg = "Exception in _post_teardown."
|
|
_post_teardown.side_effect = Exception(msg)
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("simple_test"))
|
|
with self.assertRaisesMessage(Exception, msg):
|
|
# This is the same as test_suite.debug().
|
|
result = _DebugResult()
|
|
test_suite.run(result, debug=True)
|
|
# pre-setup and post-teardwn are called.
|
|
_pre_setup.assert_called_once_with()
|
|
_post_teardown.assert_called_once_with()
|
|
self.isolate_debug_test(test_suite, result)
|
|
|
|
def test_debug_skipped_test_no_cleanup(self, _pre_setup, _post_teardown):
|
|
test_suite = unittest.TestSuite()
|
|
test_suite.addTest(ErrorTestCase("skipped_test"))
|
|
with self.assertRaisesMessage(unittest.SkipTest, "Skip condition."):
|
|
# This is the same as test_suite.debug().
|
|
result = _DebugResult()
|
|
test_suite.run(result, debug=True)
|
|
self.assertFalse(_post_teardown.called)
|
|
self.assertFalse(_pre_setup.called)
|
|
self.isolate_debug_test(test_suite, result)
|