test_setups.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. import io
  2. import sys
  3. import unittest
  4. def resultFactory(*_):
  5. return unittest.TestResult()
  6. class TestSetups(unittest.TestCase):
  7. def getRunner(self):
  8. return unittest.TextTestRunner(resultclass=resultFactory,
  9. stream=io.StringIO())
  10. def runTests(self, *cases):
  11. suite = unittest.TestSuite()
  12. for case in cases:
  13. tests = unittest.defaultTestLoader.loadTestsFromTestCase(case)
  14. suite.addTests(tests)
  15. runner = self.getRunner()
  16. # creating a nested suite exposes some potential bugs
  17. realSuite = unittest.TestSuite()
  18. realSuite.addTest(suite)
  19. # adding empty suites to the end exposes potential bugs
  20. suite.addTest(unittest.TestSuite())
  21. realSuite.addTest(unittest.TestSuite())
  22. return runner.run(realSuite)
  23. def test_setup_class(self):
  24. class Test(unittest.TestCase):
  25. setUpCalled = 0
  26. @classmethod
  27. def setUpClass(cls):
  28. Test.setUpCalled += 1
  29. unittest.TestCase.setUpClass()
  30. def test_one(self):
  31. pass
  32. def test_two(self):
  33. pass
  34. result = self.runTests(Test)
  35. self.assertEqual(Test.setUpCalled, 1)
  36. self.assertEqual(result.testsRun, 2)
  37. self.assertEqual(len(result.errors), 0)
  38. def test_teardown_class(self):
  39. class Test(unittest.TestCase):
  40. tearDownCalled = 0
  41. @classmethod
  42. def tearDownClass(cls):
  43. Test.tearDownCalled += 1
  44. unittest.TestCase.tearDownClass()
  45. def test_one(self):
  46. pass
  47. def test_two(self):
  48. pass
  49. result = self.runTests(Test)
  50. self.assertEqual(Test.tearDownCalled, 1)
  51. self.assertEqual(result.testsRun, 2)
  52. self.assertEqual(len(result.errors), 0)
  53. def test_teardown_class_two_classes(self):
  54. class Test(unittest.TestCase):
  55. tearDownCalled = 0
  56. @classmethod
  57. def tearDownClass(cls):
  58. Test.tearDownCalled += 1
  59. unittest.TestCase.tearDownClass()
  60. def test_one(self):
  61. pass
  62. def test_two(self):
  63. pass
  64. class Test2(unittest.TestCase):
  65. tearDownCalled = 0
  66. @classmethod
  67. def tearDownClass(cls):
  68. Test2.tearDownCalled += 1
  69. unittest.TestCase.tearDownClass()
  70. def test_one(self):
  71. pass
  72. def test_two(self):
  73. pass
  74. result = self.runTests(Test, Test2)
  75. self.assertEqual(Test.tearDownCalled, 1)
  76. self.assertEqual(Test2.tearDownCalled, 1)
  77. self.assertEqual(result.testsRun, 4)
  78. self.assertEqual(len(result.errors), 0)
  79. def test_error_in_setupclass(self):
  80. class BrokenTest(unittest.TestCase):
  81. @classmethod
  82. def setUpClass(cls):
  83. raise TypeError('foo')
  84. def test_one(self):
  85. pass
  86. def test_two(self):
  87. pass
  88. result = self.runTests(BrokenTest)
  89. self.assertEqual(result.testsRun, 0)
  90. self.assertEqual(len(result.errors), 1)
  91. error, _ = result.errors[0]
  92. self.assertEqual(str(error),
  93. 'setUpClass (%s.%s)' % (__name__, BrokenTest.__qualname__))
  94. def test_error_in_teardown_class(self):
  95. class Test(unittest.TestCase):
  96. tornDown = 0
  97. @classmethod
  98. def tearDownClass(cls):
  99. Test.tornDown += 1
  100. raise TypeError('foo')
  101. def test_one(self):
  102. pass
  103. def test_two(self):
  104. pass
  105. class Test2(unittest.TestCase):
  106. tornDown = 0
  107. @classmethod
  108. def tearDownClass(cls):
  109. Test2.tornDown += 1
  110. raise TypeError('foo')
  111. def test_one(self):
  112. pass
  113. def test_two(self):
  114. pass
  115. result = self.runTests(Test, Test2)
  116. self.assertEqual(result.testsRun, 4)
  117. self.assertEqual(len(result.errors), 2)
  118. self.assertEqual(Test.tornDown, 1)
  119. self.assertEqual(Test2.tornDown, 1)
  120. error, _ = result.errors[0]
  121. self.assertEqual(str(error),
  122. 'tearDownClass (%s.%s)' % (__name__, Test.__qualname__))
  123. def test_class_not_torndown_when_setup_fails(self):
  124. class Test(unittest.TestCase):
  125. tornDown = False
  126. @classmethod
  127. def setUpClass(cls):
  128. raise TypeError
  129. @classmethod
  130. def tearDownClass(cls):
  131. Test.tornDown = True
  132. raise TypeError('foo')
  133. def test_one(self):
  134. pass
  135. self.runTests(Test)
  136. self.assertFalse(Test.tornDown)
  137. def test_class_not_setup_or_torndown_when_skipped(self):
  138. class Test(unittest.TestCase):
  139. classSetUp = False
  140. tornDown = False
  141. @classmethod
  142. def setUpClass(cls):
  143. Test.classSetUp = True
  144. @classmethod
  145. def tearDownClass(cls):
  146. Test.tornDown = True
  147. def test_one(self):
  148. pass
  149. Test = unittest.skip("hop")(Test)
  150. self.runTests(Test)
  151. self.assertFalse(Test.classSetUp)
  152. self.assertFalse(Test.tornDown)
  153. def test_setup_teardown_order_with_pathological_suite(self):
  154. results = []
  155. class Module1(object):
  156. @staticmethod
  157. def setUpModule():
  158. results.append('Module1.setUpModule')
  159. @staticmethod
  160. def tearDownModule():
  161. results.append('Module1.tearDownModule')
  162. class Module2(object):
  163. @staticmethod
  164. def setUpModule():
  165. results.append('Module2.setUpModule')
  166. @staticmethod
  167. def tearDownModule():
  168. results.append('Module2.tearDownModule')
  169. class Test1(unittest.TestCase):
  170. @classmethod
  171. def setUpClass(cls):
  172. results.append('setup 1')
  173. @classmethod
  174. def tearDownClass(cls):
  175. results.append('teardown 1')
  176. def testOne(self):
  177. results.append('Test1.testOne')
  178. def testTwo(self):
  179. results.append('Test1.testTwo')
  180. class Test2(unittest.TestCase):
  181. @classmethod
  182. def setUpClass(cls):
  183. results.append('setup 2')
  184. @classmethod
  185. def tearDownClass(cls):
  186. results.append('teardown 2')
  187. def testOne(self):
  188. results.append('Test2.testOne')
  189. def testTwo(self):
  190. results.append('Test2.testTwo')
  191. class Test3(unittest.TestCase):
  192. @classmethod
  193. def setUpClass(cls):
  194. results.append('setup 3')
  195. @classmethod
  196. def tearDownClass(cls):
  197. results.append('teardown 3')
  198. def testOne(self):
  199. results.append('Test3.testOne')
  200. def testTwo(self):
  201. results.append('Test3.testTwo')
  202. Test1.__module__ = Test2.__module__ = 'Module'
  203. Test3.__module__ = 'Module2'
  204. sys.modules['Module'] = Module1
  205. sys.modules['Module2'] = Module2
  206. first = unittest.TestSuite((Test1('testOne'),))
  207. second = unittest.TestSuite((Test1('testTwo'),))
  208. third = unittest.TestSuite((Test2('testOne'),))
  209. fourth = unittest.TestSuite((Test2('testTwo'),))
  210. fifth = unittest.TestSuite((Test3('testOne'),))
  211. sixth = unittest.TestSuite((Test3('testTwo'),))
  212. suite = unittest.TestSuite((first, second, third, fourth, fifth, sixth))
  213. runner = self.getRunner()
  214. result = runner.run(suite)
  215. self.assertEqual(result.testsRun, 6)
  216. self.assertEqual(len(result.errors), 0)
  217. self.assertEqual(results,
  218. ['Module1.setUpModule', 'setup 1',
  219. 'Test1.testOne', 'Test1.testTwo', 'teardown 1',
  220. 'setup 2', 'Test2.testOne', 'Test2.testTwo',
  221. 'teardown 2', 'Module1.tearDownModule',
  222. 'Module2.setUpModule', 'setup 3',
  223. 'Test3.testOne', 'Test3.testTwo',
  224. 'teardown 3', 'Module2.tearDownModule'])
  225. def test_setup_module(self):
  226. class Module(object):
  227. moduleSetup = 0
  228. @staticmethod
  229. def setUpModule():
  230. Module.moduleSetup += 1
  231. class Test(unittest.TestCase):
  232. def test_one(self):
  233. pass
  234. def test_two(self):
  235. pass
  236. Test.__module__ = 'Module'
  237. sys.modules['Module'] = Module
  238. result = self.runTests(Test)
  239. self.assertEqual(Module.moduleSetup, 1)
  240. self.assertEqual(result.testsRun, 2)
  241. self.assertEqual(len(result.errors), 0)
  242. def test_error_in_setup_module(self):
  243. class Module(object):
  244. moduleSetup = 0
  245. moduleTornDown = 0
  246. @staticmethod
  247. def setUpModule():
  248. Module.moduleSetup += 1
  249. raise TypeError('foo')
  250. @staticmethod
  251. def tearDownModule():
  252. Module.moduleTornDown += 1
  253. class Test(unittest.TestCase):
  254. classSetUp = False
  255. classTornDown = False
  256. @classmethod
  257. def setUpClass(cls):
  258. Test.classSetUp = True
  259. @classmethod
  260. def tearDownClass(cls):
  261. Test.classTornDown = True
  262. def test_one(self):
  263. pass
  264. def test_two(self):
  265. pass
  266. class Test2(unittest.TestCase):
  267. def test_one(self):
  268. pass
  269. def test_two(self):
  270. pass
  271. Test.__module__ = 'Module'
  272. Test2.__module__ = 'Module'
  273. sys.modules['Module'] = Module
  274. result = self.runTests(Test, Test2)
  275. self.assertEqual(Module.moduleSetup, 1)
  276. self.assertEqual(Module.moduleTornDown, 0)
  277. self.assertEqual(result.testsRun, 0)
  278. self.assertFalse(Test.classSetUp)
  279. self.assertFalse(Test.classTornDown)
  280. self.assertEqual(len(result.errors), 1)
  281. error, _ = result.errors[0]
  282. self.assertEqual(str(error), 'setUpModule (Module)')
  283. def test_testcase_with_missing_module(self):
  284. class Test(unittest.TestCase):
  285. def test_one(self):
  286. pass
  287. def test_two(self):
  288. pass
  289. Test.__module__ = 'Module'
  290. sys.modules.pop('Module', None)
  291. result = self.runTests(Test)
  292. self.assertEqual(result.testsRun, 2)
  293. def test_teardown_module(self):
  294. class Module(object):
  295. moduleTornDown = 0
  296. @staticmethod
  297. def tearDownModule():
  298. Module.moduleTornDown += 1
  299. class Test(unittest.TestCase):
  300. def test_one(self):
  301. pass
  302. def test_two(self):
  303. pass
  304. Test.__module__ = 'Module'
  305. sys.modules['Module'] = Module
  306. result = self.runTests(Test)
  307. self.assertEqual(Module.moduleTornDown, 1)
  308. self.assertEqual(result.testsRun, 2)
  309. self.assertEqual(len(result.errors), 0)
  310. def test_error_in_teardown_module(self):
  311. class Module(object):
  312. moduleTornDown = 0
  313. @staticmethod
  314. def tearDownModule():
  315. Module.moduleTornDown += 1
  316. raise TypeError('foo')
  317. class Test(unittest.TestCase):
  318. classSetUp = False
  319. classTornDown = False
  320. @classmethod
  321. def setUpClass(cls):
  322. Test.classSetUp = True
  323. @classmethod
  324. def tearDownClass(cls):
  325. Test.classTornDown = True
  326. def test_one(self):
  327. pass
  328. def test_two(self):
  329. pass
  330. class Test2(unittest.TestCase):
  331. def test_one(self):
  332. pass
  333. def test_two(self):
  334. pass
  335. Test.__module__ = 'Module'
  336. Test2.__module__ = 'Module'
  337. sys.modules['Module'] = Module
  338. result = self.runTests(Test, Test2)
  339. self.assertEqual(Module.moduleTornDown, 1)
  340. self.assertEqual(result.testsRun, 4)
  341. self.assertTrue(Test.classSetUp)
  342. self.assertTrue(Test.classTornDown)
  343. self.assertEqual(len(result.errors), 1)
  344. error, _ = result.errors[0]
  345. self.assertEqual(str(error), 'tearDownModule (Module)')
  346. def test_skiptest_in_setupclass(self):
  347. class Test(unittest.TestCase):
  348. @classmethod
  349. def setUpClass(cls):
  350. raise unittest.SkipTest('foo')
  351. def test_one(self):
  352. pass
  353. def test_two(self):
  354. pass
  355. result = self.runTests(Test)
  356. self.assertEqual(result.testsRun, 0)
  357. self.assertEqual(len(result.errors), 0)
  358. self.assertEqual(len(result.skipped), 1)
  359. skipped = result.skipped[0][0]
  360. self.assertEqual(str(skipped),
  361. 'setUpClass (%s.%s)' % (__name__, Test.__qualname__))
  362. def test_skiptest_in_setupmodule(self):
  363. class Test(unittest.TestCase):
  364. def test_one(self):
  365. pass
  366. def test_two(self):
  367. pass
  368. class Module(object):
  369. @staticmethod
  370. def setUpModule():
  371. raise unittest.SkipTest('foo')
  372. Test.__module__ = 'Module'
  373. sys.modules['Module'] = Module
  374. result = self.runTests(Test)
  375. self.assertEqual(result.testsRun, 0)
  376. self.assertEqual(len(result.errors), 0)
  377. self.assertEqual(len(result.skipped), 1)
  378. skipped = result.skipped[0][0]
  379. self.assertEqual(str(skipped), 'setUpModule (Module)')
  380. def test_suite_debug_executes_setups_and_teardowns(self):
  381. ordering = []
  382. class Module(object):
  383. @staticmethod
  384. def setUpModule():
  385. ordering.append('setUpModule')
  386. @staticmethod
  387. def tearDownModule():
  388. ordering.append('tearDownModule')
  389. class Test(unittest.TestCase):
  390. @classmethod
  391. def setUpClass(cls):
  392. ordering.append('setUpClass')
  393. @classmethod
  394. def tearDownClass(cls):
  395. ordering.append('tearDownClass')
  396. def test_something(self):
  397. ordering.append('test_something')
  398. Test.__module__ = 'Module'
  399. sys.modules['Module'] = Module
  400. suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
  401. suite.debug()
  402. expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule']
  403. self.assertEqual(ordering, expectedOrder)
  404. def test_suite_debug_propagates_exceptions(self):
  405. class Module(object):
  406. @staticmethod
  407. def setUpModule():
  408. if phase == 0:
  409. raise Exception('setUpModule')
  410. @staticmethod
  411. def tearDownModule():
  412. if phase == 1:
  413. raise Exception('tearDownModule')
  414. class Test(unittest.TestCase):
  415. @classmethod
  416. def setUpClass(cls):
  417. if phase == 2:
  418. raise Exception('setUpClass')
  419. @classmethod
  420. def tearDownClass(cls):
  421. if phase == 3:
  422. raise Exception('tearDownClass')
  423. def test_something(self):
  424. if phase == 4:
  425. raise Exception('test_something')
  426. Test.__module__ = 'Module'
  427. sys.modules['Module'] = Module
  428. messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something')
  429. for phase, msg in enumerate(messages):
  430. _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
  431. suite = unittest.TestSuite([_suite])
  432. with self.assertRaisesRegex(Exception, msg):
  433. suite.debug()
  434. if __name__ == '__main__':
  435. unittest.main()