1
1
import pickle
2
2
import sys
3
3
import unittest
4
+ from unittest .case import TestCase
5
+ from unittest .result import TestResult
6
+ from unittest .suite import TestSuite , _ErrorHolder
4
7
5
8
from django .test import SimpleTestCase
6
- from django .test .runner import RemoteTestResult
9
+ from django .test .runner import ParallelTestSuite , RemoteTestResult
7
10
from django .utils .version import PY311 , PY312
8
11
9
12
try :
@@ -59,6 +62,18 @@ def pickle_error_test(self):
59
62
self .fail ("expected failure" )
60
63
61
64
65
+ class SampleErrorTest (SimpleTestCase ):
66
+ @classmethod
67
+ def setUpClass (cls ):
68
+ raise ValueError ("woops" )
69
+ super ().setUpClass ()
70
+
71
+ # This method name doesn't begin with "test" to prevent test discovery
72
+ # from seeing it.
73
+ def dummy_test (self ):
74
+ raise AssertionError ("SampleErrorTest.dummy_test() was called" )
75
+
76
+
62
77
class RemoteTestResultTest (SimpleTestCase ):
63
78
def _test_error_exc_info (self ):
64
79
try :
@@ -72,29 +87,70 @@ def test_was_successful_no_events(self):
72
87
73
88
def test_was_successful_one_success (self ):
74
89
result = RemoteTestResult ()
75
- result .addSuccess (None )
90
+ test = None
91
+ result .startTest (test )
92
+ try :
93
+ result .addSuccess (test )
94
+ finally :
95
+ result .stopTest (test )
76
96
self .assertIs (result .wasSuccessful (), True )
77
97
78
98
def test_was_successful_one_expected_failure (self ):
79
99
result = RemoteTestResult ()
80
- result .addExpectedFailure (None , self ._test_error_exc_info ())
100
+ test = None
101
+ result .startTest (test )
102
+ try :
103
+ result .addExpectedFailure (test , self ._test_error_exc_info ())
104
+ finally :
105
+ result .stopTest (test )
81
106
self .assertIs (result .wasSuccessful (), True )
82
107
83
108
def test_was_successful_one_skip (self ):
84
109
result = RemoteTestResult ()
85
- result .addSkip (None , "Skipped" )
110
+ test = None
111
+ result .startTest (test )
112
+ try :
113
+ result .addSkip (test , "Skipped" )
114
+ finally :
115
+ result .stopTest (test )
86
116
self .assertIs (result .wasSuccessful (), True )
87
117
88
118
@unittest .skipUnless (tblib is not None , "requires tblib to be installed" )
89
119
def test_was_successful_one_error (self ):
90
120
result = RemoteTestResult ()
91
- result .addError (None , self ._test_error_exc_info ())
121
+ test = None
122
+ result .startTest (test )
123
+ try :
124
+ result .addError (test , self ._test_error_exc_info ())
125
+ finally :
126
+ result .stopTest (test )
92
127
self .assertIs (result .wasSuccessful (), False )
93
128
94
129
@unittest .skipUnless (tblib is not None , "requires tblib to be installed" )
95
130
def test_was_successful_one_failure (self ):
96
131
result = RemoteTestResult ()
97
- result .addFailure (None , self ._test_error_exc_info ())
132
+ test = None
133
+ result .startTest (test )
134
+ try :
135
+ result .addFailure (test , self ._test_error_exc_info ())
136
+ finally :
137
+ result .stopTest (test )
138
+ self .assertIs (result .wasSuccessful (), False )
139
+
140
+ @unittest .skipUnless (tblib is not None , "requires tblib to be installed" )
141
+ def test_add_error_before_first_test (self ):
142
+ result = RemoteTestResult ()
143
+ test_id = "test_foo (tests.test_foo.FooTest.test_foo)"
144
+ test = _ErrorHolder (test_id )
145
+ # Call addError() without a call to startTest().
146
+ result .addError (test , self ._test_error_exc_info ())
147
+
148
+ (event ,) = result .events
149
+ self .assertEqual (event [0 ], "addError" )
150
+ self .assertEqual (event [1 ], - 1 )
151
+ self .assertEqual (event [2 ], test_id )
152
+ (error_type , _ , _ ) = event [3 ]
153
+ self .assertEqual (error_type , ValueError )
98
154
self .assertIs (result .wasSuccessful (), False )
99
155
100
156
def test_picklable (self ):
@@ -161,3 +217,75 @@ def test_add_duration(self):
161
217
result = RemoteTestResult ()
162
218
result .addDuration (None , 2.3 )
163
219
self .assertEqual (result .collectedDurations , [("None" , 2.3 )])
220
+
221
+
222
+ class ParallelTestSuiteTest (SimpleTestCase ):
223
+ def test_handle_add_error_before_first_test (self ):
224
+ dummy_subsuites = []
225
+ pts = ParallelTestSuite (dummy_subsuites , processes = 2 )
226
+ result = TestResult ()
227
+ remote_result = RemoteTestResult ()
228
+ test = SampleErrorTest (methodName = "dummy_test" )
229
+ suite = TestSuite ([test ])
230
+ suite .run (remote_result )
231
+ for event in remote_result .events :
232
+ pts .handle_event (result , tests = list (suite ), event = event )
233
+
234
+ self .assertEqual (len (result .errors ), 1 )
235
+ actual_test , tb_and_details_str = result .errors [0 ]
236
+ self .assertIsInstance (actual_test , _ErrorHolder )
237
+ self .assertEqual (
238
+ actual_test .id (), "setUpClass (test_runner.test_parallel.SampleErrorTest)"
239
+ )
240
+ self .assertIn ("Traceback (most recent call last):" , tb_and_details_str )
241
+ self .assertIn ("ValueError: woops" , tb_and_details_str )
242
+
243
+ def test_handle_add_error_during_test (self ):
244
+ dummy_subsuites = []
245
+ pts = ParallelTestSuite (dummy_subsuites , processes = 2 )
246
+ result = TestResult ()
247
+ test = TestCase ()
248
+ err = _test_error_exc_info ()
249
+ event = ("addError" , 0 , err )
250
+ pts .handle_event (result , tests = [test ], event = event )
251
+
252
+ self .assertEqual (len (result .errors ), 1 )
253
+ actual_test , tb_and_details_str = result .errors [0 ]
254
+ self .assertIsInstance (actual_test , TestCase )
255
+ self .assertEqual (actual_test .id (), "unittest.case.TestCase.runTest" )
256
+ self .assertIn ("Traceback (most recent call last):" , tb_and_details_str )
257
+ self .assertIn ("ValueError: woops" , tb_and_details_str )
258
+
259
+ def test_handle_add_failure (self ):
260
+ dummy_subsuites = []
261
+ pts = ParallelTestSuite (dummy_subsuites , processes = 2 )
262
+ result = TestResult ()
263
+ test = TestCase ()
264
+ err = _test_error_exc_info ()
265
+ event = ("addFailure" , 0 , err )
266
+ pts .handle_event (result , tests = [test ], event = event )
267
+
268
+ self .assertEqual (len (result .failures ), 1 )
269
+ actual_test , tb_and_details_str = result .failures [0 ]
270
+ self .assertIsInstance (actual_test , TestCase )
271
+ self .assertEqual (actual_test .id (), "unittest.case.TestCase.runTest" )
272
+ self .assertIn ("Traceback (most recent call last):" , tb_and_details_str )
273
+ self .assertIn ("ValueError: woops" , tb_and_details_str )
274
+
275
+ def test_handle_add_success (self ):
276
+ dummy_subsuites = []
277
+ pts = ParallelTestSuite (dummy_subsuites , processes = 2 )
278
+ result = TestResult ()
279
+ test = TestCase ()
280
+ event = ("addSuccess" , 0 )
281
+ pts .handle_event (result , tests = [test ], event = event )
282
+
283
+ self .assertEqual (len (result .errors ), 0 )
284
+ self .assertEqual (len (result .failures ), 0 )
285
+
286
+
287
+ def _test_error_exc_info ():
288
+ try :
289
+ raise ValueError ("woops" )
290
+ except ValueError :
291
+ return sys .exc_info ()
0 commit comments