1import unittest 2 3import gc 4import sys 5import weakref 6from unittest.test.support import LoggingResult, TestEquality 7 8 9### Support code for Test_TestSuite 10################################################################ 11 12class Test(object): 13 class Foo(unittest.TestCase): 14 def test_1(self): pass 15 def test_2(self): pass 16 def test_3(self): pass 17 def runTest(self): pass 18 19def _mk_TestSuite(*names): 20 return unittest.TestSuite(Test.Foo(n) for n in names) 21 22################################################################ 23 24 25class Test_TestSuite(unittest.TestCase, TestEquality): 26 27 ### Set up attributes needed by inherited tests 28 ################################################################ 29 30 # Used by TestEquality.test_eq 31 eq_pairs = [(unittest.TestSuite(), unittest.TestSuite()) 32 ,(unittest.TestSuite(), unittest.TestSuite([])) 33 ,(_mk_TestSuite('test_1'), _mk_TestSuite('test_1'))] 34 35 # Used by TestEquality.test_ne 36 ne_pairs = [(unittest.TestSuite(), _mk_TestSuite('test_1')) 37 ,(unittest.TestSuite([]), _mk_TestSuite('test_1')) 38 ,(_mk_TestSuite('test_1', 'test_2'), _mk_TestSuite('test_1', 'test_3')) 39 ,(_mk_TestSuite('test_1'), _mk_TestSuite('test_2'))] 40 41 ################################################################ 42 ### /Set up attributes needed by inherited tests 43 44 ### Tests for TestSuite.__init__ 45 ################################################################ 46 47 # "class TestSuite([tests])" 48 # 49 # The tests iterable should be optional 50 def test_init__tests_optional(self): 51 suite = unittest.TestSuite() 52 53 self.assertEqual(suite.countTestCases(), 0) 54 # countTestCases() still works after tests are run 55 suite.run(unittest.TestResult()) 56 self.assertEqual(suite.countTestCases(), 0) 57 58 # "class TestSuite([tests])" 59 # ... 60 # "If tests is given, it must be an iterable of individual test cases 61 # or other test suites that will be used to build the suite initially" 62 # 63 # TestSuite should deal with empty tests iterables by allowing the 64 # creation of an empty suite 65 def test_init__empty_tests(self): 66 suite = unittest.TestSuite([]) 67 68 self.assertEqual(suite.countTestCases(), 0) 69 # countTestCases() still works after tests are run 70 suite.run(unittest.TestResult()) 71 self.assertEqual(suite.countTestCases(), 0) 72 73 # "class TestSuite([tests])" 74 # ... 75 # "If tests is given, it must be an iterable of individual test cases 76 # or other test suites that will be used to build the suite initially" 77 # 78 # TestSuite should allow any iterable to provide tests 79 def test_init__tests_from_any_iterable(self): 80 def tests(): 81 yield unittest.FunctionTestCase(lambda: None) 82 yield unittest.FunctionTestCase(lambda: None) 83 84 suite_1 = unittest.TestSuite(tests()) 85 self.assertEqual(suite_1.countTestCases(), 2) 86 87 suite_2 = unittest.TestSuite(suite_1) 88 self.assertEqual(suite_2.countTestCases(), 2) 89 90 suite_3 = unittest.TestSuite(set(suite_1)) 91 self.assertEqual(suite_3.countTestCases(), 2) 92 93 # countTestCases() still works after tests are run 94 suite_1.run(unittest.TestResult()) 95 self.assertEqual(suite_1.countTestCases(), 2) 96 suite_2.run(unittest.TestResult()) 97 self.assertEqual(suite_2.countTestCases(), 2) 98 suite_3.run(unittest.TestResult()) 99 self.assertEqual(suite_3.countTestCases(), 2) 100 101 # "class TestSuite([tests])" 102 # ... 103 # "If tests is given, it must be an iterable of individual test cases 104 # or other test suites that will be used to build the suite initially" 105 # 106 # Does TestSuite() also allow other TestSuite() instances to be present 107 # in the tests iterable? 108 def test_init__TestSuite_instances_in_tests(self): 109 def tests(): 110 ftc = unittest.FunctionTestCase(lambda: None) 111 yield unittest.TestSuite([ftc]) 112 yield unittest.FunctionTestCase(lambda: None) 113 114 suite = unittest.TestSuite(tests()) 115 self.assertEqual(suite.countTestCases(), 2) 116 # countTestCases() still works after tests are run 117 suite.run(unittest.TestResult()) 118 self.assertEqual(suite.countTestCases(), 2) 119 120 ################################################################ 121 ### /Tests for TestSuite.__init__ 122 123 # Container types should support the iter protocol 124 def test_iter(self): 125 test1 = unittest.FunctionTestCase(lambda: None) 126 test2 = unittest.FunctionTestCase(lambda: None) 127 suite = unittest.TestSuite((test1, test2)) 128 129 self.assertEqual(list(suite), [test1, test2]) 130 131 # "Return the number of tests represented by the this test object. 132 # ...this method is also implemented by the TestSuite class, which can 133 # return larger [greater than 1] values" 134 # 135 # Presumably an empty TestSuite returns 0? 136 def test_countTestCases_zero_simple(self): 137 suite = unittest.TestSuite() 138 139 self.assertEqual(suite.countTestCases(), 0) 140 141 # "Return the number of tests represented by the this test object. 142 # ...this method is also implemented by the TestSuite class, which can 143 # return larger [greater than 1] values" 144 # 145 # Presumably an empty TestSuite (even if it contains other empty 146 # TestSuite instances) returns 0? 147 def test_countTestCases_zero_nested(self): 148 class Test1(unittest.TestCase): 149 def test(self): 150 pass 151 152 suite = unittest.TestSuite([unittest.TestSuite()]) 153 154 self.assertEqual(suite.countTestCases(), 0) 155 156 # "Return the number of tests represented by the this test object. 157 # ...this method is also implemented by the TestSuite class, which can 158 # return larger [greater than 1] values" 159 def test_countTestCases_simple(self): 160 test1 = unittest.FunctionTestCase(lambda: None) 161 test2 = unittest.FunctionTestCase(lambda: None) 162 suite = unittest.TestSuite((test1, test2)) 163 164 self.assertEqual(suite.countTestCases(), 2) 165 # countTestCases() still works after tests are run 166 suite.run(unittest.TestResult()) 167 self.assertEqual(suite.countTestCases(), 2) 168 169 # "Return the number of tests represented by the this test object. 170 # ...this method is also implemented by the TestSuite class, which can 171 # return larger [greater than 1] values" 172 # 173 # Make sure this holds for nested TestSuite instances, too 174 def test_countTestCases_nested(self): 175 class Test1(unittest.TestCase): 176 def test1(self): pass 177 def test2(self): pass 178 179 test2 = unittest.FunctionTestCase(lambda: None) 180 test3 = unittest.FunctionTestCase(lambda: None) 181 child = unittest.TestSuite((Test1('test2'), test2)) 182 parent = unittest.TestSuite((test3, child, Test1('test1'))) 183 184 self.assertEqual(parent.countTestCases(), 4) 185 # countTestCases() still works after tests are run 186 parent.run(unittest.TestResult()) 187 self.assertEqual(parent.countTestCases(), 4) 188 self.assertEqual(child.countTestCases(), 2) 189 190 # "Run the tests associated with this suite, collecting the result into 191 # the test result object passed as result." 192 # 193 # And if there are no tests? What then? 194 def test_run__empty_suite(self): 195 events = [] 196 result = LoggingResult(events) 197 198 suite = unittest.TestSuite() 199 200 suite.run(result) 201 202 self.assertEqual(events, []) 203 204 # "Note that unlike TestCase.run(), TestSuite.run() requires the 205 # "result object to be passed in." 206 def test_run__requires_result(self): 207 suite = unittest.TestSuite() 208 209 try: 210 suite.run() 211 except TypeError: 212 pass 213 else: 214 self.fail("Failed to raise TypeError") 215 216 # "Run the tests associated with this suite, collecting the result into 217 # the test result object passed as result." 218 def test_run(self): 219 events = [] 220 result = LoggingResult(events) 221 222 class LoggingCase(unittest.TestCase): 223 def run(self, result): 224 events.append('run %s' % self._testMethodName) 225 226 def test1(self): pass 227 def test2(self): pass 228 229 tests = [LoggingCase('test1'), LoggingCase('test2')] 230 231 unittest.TestSuite(tests).run(result) 232 233 self.assertEqual(events, ['run test1', 'run test2']) 234 235 # "Add a TestCase ... to the suite" 236 def test_addTest__TestCase(self): 237 class Foo(unittest.TestCase): 238 def test(self): pass 239 240 test = Foo('test') 241 suite = unittest.TestSuite() 242 243 suite.addTest(test) 244 245 self.assertEqual(suite.countTestCases(), 1) 246 self.assertEqual(list(suite), [test]) 247 # countTestCases() still works after tests are run 248 suite.run(unittest.TestResult()) 249 self.assertEqual(suite.countTestCases(), 1) 250 251 # "Add a ... TestSuite to the suite" 252 def test_addTest__TestSuite(self): 253 class Foo(unittest.TestCase): 254 def test(self): pass 255 256 suite_2 = unittest.TestSuite([Foo('test')]) 257 258 suite = unittest.TestSuite() 259 suite.addTest(suite_2) 260 261 self.assertEqual(suite.countTestCases(), 1) 262 self.assertEqual(list(suite), [suite_2]) 263 # countTestCases() still works after tests are run 264 suite.run(unittest.TestResult()) 265 self.assertEqual(suite.countTestCases(), 1) 266 267 # "Add all the tests from an iterable of TestCase and TestSuite 268 # instances to this test suite." 269 # 270 # "This is equivalent to iterating over tests, calling addTest() for 271 # each element" 272 def test_addTests(self): 273 class Foo(unittest.TestCase): 274 def test_1(self): pass 275 def test_2(self): pass 276 277 test_1 = Foo('test_1') 278 test_2 = Foo('test_2') 279 inner_suite = unittest.TestSuite([test_2]) 280 281 def gen(): 282 yield test_1 283 yield test_2 284 yield inner_suite 285 286 suite_1 = unittest.TestSuite() 287 suite_1.addTests(gen()) 288 289 self.assertEqual(list(suite_1), list(gen())) 290 291 # "This is equivalent to iterating over tests, calling addTest() for 292 # each element" 293 suite_2 = unittest.TestSuite() 294 for t in gen(): 295 suite_2.addTest(t) 296 297 self.assertEqual(suite_1, suite_2) 298 299 # "Add all the tests from an iterable of TestCase and TestSuite 300 # instances to this test suite." 301 # 302 # What happens if it doesn't get an iterable? 303 def test_addTest__noniterable(self): 304 suite = unittest.TestSuite() 305 306 try: 307 suite.addTests(5) 308 except TypeError: 309 pass 310 else: 311 self.fail("Failed to raise TypeError") 312 313 def test_addTest__noncallable(self): 314 suite = unittest.TestSuite() 315 self.assertRaises(TypeError, suite.addTest, 5) 316 317 def test_addTest__casesuiteclass(self): 318 suite = unittest.TestSuite() 319 self.assertRaises(TypeError, suite.addTest, Test_TestSuite) 320 self.assertRaises(TypeError, suite.addTest, unittest.TestSuite) 321 322 def test_addTests__string(self): 323 suite = unittest.TestSuite() 324 self.assertRaises(TypeError, suite.addTests, "foo") 325 326 def test_function_in_suite(self): 327 def f(_): 328 pass 329 suite = unittest.TestSuite() 330 suite.addTest(f) 331 332 # when the bug is fixed this line will not crash 333 suite.run(unittest.TestResult()) 334 335 def test_remove_test_at_index(self): 336 if not unittest.BaseTestSuite._cleanup: 337 raise unittest.SkipTest("Suite cleanup is disabled") 338 339 suite = unittest.TestSuite() 340 341 suite._tests = [1, 2, 3] 342 suite._removeTestAtIndex(1) 343 344 self.assertEqual([1, None, 3], suite._tests) 345 346 def test_remove_test_at_index_not_indexable(self): 347 if not unittest.BaseTestSuite._cleanup: 348 raise unittest.SkipTest("Suite cleanup is disabled") 349 350 suite = unittest.TestSuite() 351 suite._tests = None 352 353 # if _removeAtIndex raises for noniterables this next line will break 354 suite._removeTestAtIndex(2) 355 356 def assert_garbage_collect_test_after_run(self, TestSuiteClass): 357 if not unittest.BaseTestSuite._cleanup: 358 raise unittest.SkipTest("Suite cleanup is disabled") 359 360 class Foo(unittest.TestCase): 361 def test_nothing(self): 362 pass 363 364 test = Foo('test_nothing') 365 wref = weakref.ref(test) 366 367 suite = TestSuiteClass([wref()]) 368 suite.run(unittest.TestResult()) 369 370 del test 371 372 # for the benefit of non-reference counting implementations 373 gc.collect() 374 375 self.assertEqual(suite._tests, [None]) 376 self.assertIsNone(wref()) 377 378 def test_garbage_collect_test_after_run_BaseTestSuite(self): 379 self.assert_garbage_collect_test_after_run(unittest.BaseTestSuite) 380 381 def test_garbage_collect_test_after_run_TestSuite(self): 382 self.assert_garbage_collect_test_after_run(unittest.TestSuite) 383 384 def test_basetestsuite(self): 385 class Test(unittest.TestCase): 386 wasSetUp = False 387 wasTornDown = False 388 @classmethod 389 def setUpClass(cls): 390 cls.wasSetUp = True 391 @classmethod 392 def tearDownClass(cls): 393 cls.wasTornDown = True 394 def testPass(self): 395 pass 396 def testFail(self): 397 fail 398 class Module(object): 399 wasSetUp = False 400 wasTornDown = False 401 @staticmethod 402 def setUpModule(): 403 Module.wasSetUp = True 404 @staticmethod 405 def tearDownModule(): 406 Module.wasTornDown = True 407 408 Test.__module__ = 'Module' 409 sys.modules['Module'] = Module 410 self.addCleanup(sys.modules.pop, 'Module') 411 412 suite = unittest.BaseTestSuite() 413 suite.addTests([Test('testPass'), Test('testFail')]) 414 self.assertEqual(suite.countTestCases(), 2) 415 416 result = unittest.TestResult() 417 suite.run(result) 418 self.assertFalse(Module.wasSetUp) 419 self.assertFalse(Module.wasTornDown) 420 self.assertFalse(Test.wasSetUp) 421 self.assertFalse(Test.wasTornDown) 422 self.assertEqual(len(result.errors), 1) 423 self.assertEqual(len(result.failures), 0) 424 self.assertEqual(result.testsRun, 2) 425 self.assertEqual(suite.countTestCases(), 2) 426 427 428 def test_overriding_call(self): 429 class MySuite(unittest.TestSuite): 430 called = False 431 def __call__(self, *args, **kw): 432 self.called = True 433 unittest.TestSuite.__call__(self, *args, **kw) 434 435 suite = MySuite() 436 result = unittest.TestResult() 437 wrapper = unittest.TestSuite() 438 wrapper.addTest(suite) 439 wrapper(result) 440 self.assertTrue(suite.called) 441 442 # reusing results should be permitted even if abominable 443 self.assertFalse(result._testRunEntered) 444 445 446if __name__ == '__main__': 447 unittest.main() 448