1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
import pickle
import sys
import unittest
from django.test import SimpleTestCase
from django.test.runner import RemoteTestResult
from django.utils.version import PY311
try:
import tblib.pickling_support
except ImportError:
tblib = None
class ExceptionThatFailsUnpickling(Exception):
"""
After pickling, this class fails unpickling with an error about incorrect
arguments passed to __init__().
"""
def __init__(self, arg):
super().__init__()
class ParallelTestRunnerTest(SimpleTestCase):
"""
End-to-end tests of the parallel test runner.
These tests are only meaningful when running tests in parallel using
the --parallel option, though it doesn't hurt to run them not in
parallel.
"""
def test_subtest(self):
"""
Passing subtests work.
"""
for i in range(2):
with self.subTest(index=i):
self.assertEqual(i, i)
class SampleFailingSubtest(SimpleTestCase):
# This method name doesn't begin with "test" to prevent test discovery
# from seeing it.
def dummy_test(self):
"""
A dummy test for testing subTest failures.
"""
for i in range(3):
with self.subTest(index=i):
self.assertEqual(i, 1)
class RemoteTestResultTest(SimpleTestCase):
def _test_error_exc_info(self):
try:
raise ValueError("woops")
except ValueError:
return sys.exc_info()
def test_was_successful_no_events(self):
result = RemoteTestResult()
self.assertIs(result.wasSuccessful(), True)
def test_was_successful_one_success(self):
result = RemoteTestResult()
result.addSuccess(None)
self.assertIs(result.wasSuccessful(), True)
def test_was_successful_one_expected_failure(self):
result = RemoteTestResult()
result.addExpectedFailure(None, self._test_error_exc_info())
self.assertIs(result.wasSuccessful(), True)
def test_was_successful_one_skip(self):
result = RemoteTestResult()
result.addSkip(None, "Skipped")
self.assertIs(result.wasSuccessful(), True)
@unittest.skipUnless(tblib is not None, "requires tblib to be installed")
def test_was_successful_one_error(self):
result = RemoteTestResult()
result.addError(None, self._test_error_exc_info())
self.assertIs(result.wasSuccessful(), False)
@unittest.skipUnless(tblib is not None, "requires tblib to be installed")
def test_was_successful_one_failure(self):
result = RemoteTestResult()
result.addFailure(None, self._test_error_exc_info())
self.assertIs(result.wasSuccessful(), False)
def test_picklable(self):
result = RemoteTestResult()
loaded_result = pickle.loads(pickle.dumps(result))
self.assertEqual(result.events, loaded_result.events)
def test_pickle_errors_detection(self):
picklable_error = RuntimeError("This is fine")
not_unpicklable_error = ExceptionThatFailsUnpickling("arg")
result = RemoteTestResult()
result._confirm_picklable(picklable_error)
msg = "__init__() missing 1 required positional argument"
with self.assertRaisesMessage(TypeError, msg):
result._confirm_picklable(not_unpicklable_error)
@unittest.skipUnless(tblib is not None, "requires tblib to be installed")
def test_add_failing_subtests(self):
"""
Failing subtests are added correctly using addSubTest().
"""
# Manually run a test with failing subtests to prevent the failures
# from affecting the actual test run.
result = RemoteTestResult()
subtest_test = SampleFailingSubtest(methodName="dummy_test")
subtest_test.run(result=result)
events = result.events
self.assertEqual(len(events), 4)
self.assertIs(result.wasSuccessful(), False)
event = events[1]
self.assertEqual(event[0], "addSubTest")
self.assertEqual(
str(event[2]),
"dummy_test (test_runner.test_parallel.SampleFailingSubtest%s) (index=0)"
# Python 3.11 uses fully qualified test name in the output.
% (".dummy_test" if PY311 else ""),
)
self.assertEqual(repr(event[3][1]), "AssertionError('0 != 1')")
event = events[2]
self.assertEqual(repr(event[3][1]), "AssertionError('2 != 1')")
|