1import io 2import os 3import sys 4import pickle 5import subprocess 6 7import unittest 8from unittest.case import _Outcome 9 10from unittest.test.support import (LoggingResult, 11 ResultWithNoStartTestRunStopTestRun) 12 13 14class TestCleanUp(unittest.TestCase): 15 16 def testCleanUp(self): 17 class TestableTest(unittest.TestCase): 18 def testNothing(self): 19 pass 20 21 test = TestableTest('testNothing') 22 self.assertEqual(test._cleanups, []) 23 24 cleanups = [] 25 26 def cleanup1(*args, **kwargs): 27 cleanups.append((1, args, kwargs)) 28 29 def cleanup2(*args, **kwargs): 30 cleanups.append((2, args, kwargs)) 31 32 test.addCleanup(cleanup1, 1, 2, 3, four='hello', five='goodbye') 33 test.addCleanup(cleanup2) 34 35 self.assertEqual(test._cleanups, 36 [(cleanup1, (1, 2, 3), dict(four='hello', five='goodbye')), 37 (cleanup2, (), {})]) 38 39 self.assertTrue(test.doCleanups()) 40 self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))]) 41 42 def testCleanUpWithErrors(self): 43 class TestableTest(unittest.TestCase): 44 def testNothing(self): 45 pass 46 47 test = TestableTest('testNothing') 48 outcome = test._outcome = _Outcome() 49 50 exc1 = Exception('foo') 51 exc2 = Exception('bar') 52 def cleanup1(): 53 raise exc1 54 55 def cleanup2(): 56 raise exc2 57 58 test.addCleanup(cleanup1) 59 test.addCleanup(cleanup2) 60 61 self.assertFalse(test.doCleanups()) 62 self.assertFalse(outcome.success) 63 64 ((_, (Type1, instance1, _)), 65 (_, (Type2, instance2, _))) = reversed(outcome.errors) 66 self.assertEqual((Type1, instance1), (Exception, exc1)) 67 self.assertEqual((Type2, instance2), (Exception, exc2)) 68 69 def testCleanupInRun(self): 70 blowUp = False 71 ordering = [] 72 73 class TestableTest(unittest.TestCase): 74 def setUp(self): 75 ordering.append('setUp') 76 if blowUp: 77 raise Exception('foo') 78 79 def testNothing(self): 80 ordering.append('test') 81 82 def tearDown(self): 83 ordering.append('tearDown') 84 85 test = TestableTest('testNothing') 86 87 def cleanup1(): 88 ordering.append('cleanup1') 89 def cleanup2(): 90 ordering.append('cleanup2') 91 test.addCleanup(cleanup1) 92 test.addCleanup(cleanup2) 93 94 def success(some_test): 95 self.assertEqual(some_test, test) 96 ordering.append('success') 97 98 result = unittest.TestResult() 99 result.addSuccess = success 100 101 test.run(result) 102 self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 103 'cleanup2', 'cleanup1', 'success']) 104 105 blowUp = True 106 ordering = [] 107 test = TestableTest('testNothing') 108 test.addCleanup(cleanup1) 109 test.run(result) 110 self.assertEqual(ordering, ['setUp', 'cleanup1']) 111 112 def testTestCaseDebugExecutesCleanups(self): 113 ordering = [] 114 115 class TestableTest(unittest.TestCase): 116 def setUp(self): 117 ordering.append('setUp') 118 self.addCleanup(cleanup1) 119 120 def testNothing(self): 121 ordering.append('test') 122 123 def tearDown(self): 124 ordering.append('tearDown') 125 126 test = TestableTest('testNothing') 127 128 def cleanup1(): 129 ordering.append('cleanup1') 130 test.addCleanup(cleanup2) 131 def cleanup2(): 132 ordering.append('cleanup2') 133 134 test.debug() 135 self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) 136 137 138class Test_TextTestRunner(unittest.TestCase): 139 """Tests for TextTestRunner.""" 140 141 def setUp(self): 142 # clean the environment from pre-existing PYTHONWARNINGS to make 143 # test_warnings results consistent 144 self.pythonwarnings = os.environ.get('PYTHONWARNINGS') 145 if self.pythonwarnings: 146 del os.environ['PYTHONWARNINGS'] 147 148 def tearDown(self): 149 # bring back pre-existing PYTHONWARNINGS if present 150 if self.pythonwarnings: 151 os.environ['PYTHONWARNINGS'] = self.pythonwarnings 152 153 def test_init(self): 154 runner = unittest.TextTestRunner() 155 self.assertFalse(runner.failfast) 156 self.assertFalse(runner.buffer) 157 self.assertEqual(runner.verbosity, 1) 158 self.assertEqual(runner.warnings, None) 159 self.assertTrue(runner.descriptions) 160 self.assertEqual(runner.resultclass, unittest.TextTestResult) 161 self.assertFalse(runner.tb_locals) 162 163 def test_multiple_inheritance(self): 164 class AResult(unittest.TestResult): 165 def __init__(self, stream, descriptions, verbosity): 166 super(AResult, self).__init__(stream, descriptions, verbosity) 167 168 class ATextResult(unittest.TextTestResult, AResult): 169 pass 170 171 # This used to raise an exception due to TextTestResult not passing 172 # on arguments in its __init__ super call 173 ATextResult(None, None, 1) 174 175 def testBufferAndFailfast(self): 176 class Test(unittest.TestCase): 177 def testFoo(self): 178 pass 179 result = unittest.TestResult() 180 runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True, 181 buffer=True) 182 # Use our result object 183 runner._makeResult = lambda: result 184 runner.run(Test('testFoo')) 185 186 self.assertTrue(result.failfast) 187 self.assertTrue(result.buffer) 188 189 def test_locals(self): 190 runner = unittest.TextTestRunner(stream=io.StringIO(), tb_locals=True) 191 result = runner.run(unittest.TestSuite()) 192 self.assertEqual(True, result.tb_locals) 193 194 def testRunnerRegistersResult(self): 195 class Test(unittest.TestCase): 196 def testFoo(self): 197 pass 198 originalRegisterResult = unittest.runner.registerResult 199 def cleanup(): 200 unittest.runner.registerResult = originalRegisterResult 201 self.addCleanup(cleanup) 202 203 result = unittest.TestResult() 204 runner = unittest.TextTestRunner(stream=io.StringIO()) 205 # Use our result object 206 runner._makeResult = lambda: result 207 208 self.wasRegistered = 0 209 def fakeRegisterResult(thisResult): 210 self.wasRegistered += 1 211 self.assertEqual(thisResult, result) 212 unittest.runner.registerResult = fakeRegisterResult 213 214 runner.run(unittest.TestSuite()) 215 self.assertEqual(self.wasRegistered, 1) 216 217 def test_works_with_result_without_startTestRun_stopTestRun(self): 218 class OldTextResult(ResultWithNoStartTestRunStopTestRun): 219 separator2 = '' 220 def printErrors(self): 221 pass 222 223 class Runner(unittest.TextTestRunner): 224 def __init__(self): 225 super(Runner, self).__init__(io.StringIO()) 226 227 def _makeResult(self): 228 return OldTextResult() 229 230 runner = Runner() 231 runner.run(unittest.TestSuite()) 232 233 def test_startTestRun_stopTestRun_called(self): 234 class LoggingTextResult(LoggingResult): 235 separator2 = '' 236 def printErrors(self): 237 pass 238 239 class LoggingRunner(unittest.TextTestRunner): 240 def __init__(self, events): 241 super(LoggingRunner, self).__init__(io.StringIO()) 242 self._events = events 243 244 def _makeResult(self): 245 return LoggingTextResult(self._events) 246 247 events = [] 248 runner = LoggingRunner(events) 249 runner.run(unittest.TestSuite()) 250 expected = ['startTestRun', 'stopTestRun'] 251 self.assertEqual(events, expected) 252 253 def test_pickle_unpickle(self): 254 # Issue #7197: a TextTestRunner should be (un)pickleable. This is 255 # required by test_multiprocessing under Windows (in verbose mode). 256 stream = io.StringIO("foo") 257 runner = unittest.TextTestRunner(stream) 258 for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): 259 s = pickle.dumps(runner, protocol) 260 obj = pickle.loads(s) 261 # StringIO objects never compare equal, a cheap test instead. 262 self.assertEqual(obj.stream.getvalue(), stream.getvalue()) 263 264 def test_resultclass(self): 265 def MockResultClass(*args): 266 return args 267 STREAM = object() 268 DESCRIPTIONS = object() 269 VERBOSITY = object() 270 runner = unittest.TextTestRunner(STREAM, DESCRIPTIONS, VERBOSITY, 271 resultclass=MockResultClass) 272 self.assertEqual(runner.resultclass, MockResultClass) 273 274 expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY) 275 self.assertEqual(runner._makeResult(), expectedresult) 276 277 def test_warnings(self): 278 """ 279 Check that warnings argument of TextTestRunner correctly affects the 280 behavior of the warnings. 281 """ 282 # see #10535 and the _test_warnings file for more information 283 284 def get_parse_out_err(p): 285 return [b.splitlines() for b in p.communicate()] 286 opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE, 287 cwd=os.path.dirname(__file__)) 288 ae_msg = b'Please use assertEqual instead.' 289 at_msg = b'Please use assertTrue instead.' 290 291 # no args -> all the warnings are printed, unittest warnings only once 292 p = subprocess.Popen([sys.executable, '-E', '_test_warnings.py'], **opts) 293 with p: 294 out, err = get_parse_out_err(p) 295 self.assertIn(b'OK', err) 296 # check that the total number of warnings in the output is correct 297 self.assertEqual(len(out), 12) 298 # check that the numbers of the different kind of warnings is correct 299 for msg in [b'dw', b'iw', b'uw']: 300 self.assertEqual(out.count(msg), 3) 301 for msg in [ae_msg, at_msg, b'rw']: 302 self.assertEqual(out.count(msg), 1) 303 304 args_list = ( 305 # passing 'ignore' as warnings arg -> no warnings 306 [sys.executable, '_test_warnings.py', 'ignore'], 307 # -W doesn't affect the result if the arg is passed 308 [sys.executable, '-Wa', '_test_warnings.py', 'ignore'], 309 # -W affects the result if the arg is not passed 310 [sys.executable, '-Wi', '_test_warnings.py'] 311 ) 312 # in all these cases no warnings are printed 313 for args in args_list: 314 p = subprocess.Popen(args, **opts) 315 with p: 316 out, err = get_parse_out_err(p) 317 self.assertIn(b'OK', err) 318 self.assertEqual(len(out), 0) 319 320 321 # passing 'always' as warnings arg -> all the warnings printed, 322 # unittest warnings only once 323 p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'], 324 **opts) 325 with p: 326 out, err = get_parse_out_err(p) 327 self.assertIn(b'OK', err) 328 self.assertEqual(len(out), 14) 329 for msg in [b'dw', b'iw', b'uw', b'rw']: 330 self.assertEqual(out.count(msg), 3) 331 for msg in [ae_msg, at_msg]: 332 self.assertEqual(out.count(msg), 1) 333 334 def testStdErrLookedUpAtInstantiationTime(self): 335 # see issue 10786 336 old_stderr = sys.stderr 337 f = io.StringIO() 338 sys.stderr = f 339 try: 340 runner = unittest.TextTestRunner() 341 self.assertTrue(runner.stream.stream is f) 342 finally: 343 sys.stderr = old_stderr 344 345 def testSpecifiedStreamUsed(self): 346 # see issue 10786 347 f = io.StringIO() 348 runner = unittest.TextTestRunner(f) 349 self.assertTrue(runner.stream.stream is f) 350 351 352if __name__ == "__main__": 353 unittest.main() 354