test_loader.py 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642
  1. import functools
  2. import sys
  3. import types
  4. import warnings
  5. import unittest
  6. # Decorator used in the deprecation tests to reset the warning registry for
  7. # test isolation and reproducibility.
  8. def warningregistry(func):
  9. def wrapper(*args, **kws):
  10. missing = []
  11. saved = getattr(warnings, '__warningregistry__', missing).copy()
  12. try:
  13. return func(*args, **kws)
  14. finally:
  15. if saved is missing:
  16. try:
  17. del warnings.__warningregistry__
  18. except AttributeError:
  19. pass
  20. else:
  21. warnings.__warningregistry__ = saved
  22. return wrapper
  23. class Test_TestLoader(unittest.TestCase):
  24. ### Basic object tests
  25. ################################################################
  26. def test___init__(self):
  27. loader = unittest.TestLoader()
  28. self.assertEqual([], loader.errors)
  29. ### Tests for TestLoader.loadTestsFromTestCase
  30. ################################################################
  31. # "Return a suite of all test cases contained in the TestCase-derived
  32. # class testCaseClass"
  33. def test_loadTestsFromTestCase(self):
  34. class Foo(unittest.TestCase):
  35. def test_1(self): pass
  36. def test_2(self): pass
  37. def foo_bar(self): pass
  38. tests = unittest.TestSuite([Foo('test_1'), Foo('test_2')])
  39. loader = unittest.TestLoader()
  40. self.assertEqual(loader.loadTestsFromTestCase(Foo), tests)
  41. # "Return a suite of all test cases contained in the TestCase-derived
  42. # class testCaseClass"
  43. #
  44. # Make sure it does the right thing even if no tests were found
  45. def test_loadTestsFromTestCase__no_matches(self):
  46. class Foo(unittest.TestCase):
  47. def foo_bar(self): pass
  48. empty_suite = unittest.TestSuite()
  49. loader = unittest.TestLoader()
  50. self.assertEqual(loader.loadTestsFromTestCase(Foo), empty_suite)
  51. # "Return a suite of all test cases contained in the TestCase-derived
  52. # class testCaseClass"
  53. #
  54. # What happens if loadTestsFromTestCase() is given an object
  55. # that isn't a subclass of TestCase? Specifically, what happens
  56. # if testCaseClass is a subclass of TestSuite?
  57. #
  58. # This is checked for specifically in the code, so we better add a
  59. # test for it.
  60. def test_loadTestsFromTestCase__TestSuite_subclass(self):
  61. class NotATestCase(unittest.TestSuite):
  62. pass
  63. loader = unittest.TestLoader()
  64. try:
  65. loader.loadTestsFromTestCase(NotATestCase)
  66. except TypeError:
  67. pass
  68. else:
  69. self.fail('Should raise TypeError')
  70. # "Return a suite of all test cases contained in the TestCase-derived
  71. # class testCaseClass"
  72. #
  73. # Make sure loadTestsFromTestCase() picks up the default test method
  74. # name (as specified by TestCase), even though the method name does
  75. # not match the default TestLoader.testMethodPrefix string
  76. def test_loadTestsFromTestCase__default_method_name(self):
  77. class Foo(unittest.TestCase):
  78. def runTest(self):
  79. pass
  80. loader = unittest.TestLoader()
  81. # This has to be false for the test to succeed
  82. self.assertFalse('runTest'.startswith(loader.testMethodPrefix))
  83. suite = loader.loadTestsFromTestCase(Foo)
  84. self.assertIsInstance(suite, loader.suiteClass)
  85. self.assertEqual(list(suite), [Foo('runTest')])
  86. ################################################################
  87. ### /Tests for TestLoader.loadTestsFromTestCase
  88. ### Tests for TestLoader.loadTestsFromModule
  89. ################################################################
  90. # "This method searches `module` for classes derived from TestCase"
  91. def test_loadTestsFromModule__TestCase_subclass(self):
  92. m = types.ModuleType('m')
  93. class MyTestCase(unittest.TestCase):
  94. def test(self):
  95. pass
  96. m.testcase_1 = MyTestCase
  97. loader = unittest.TestLoader()
  98. suite = loader.loadTestsFromModule(m)
  99. self.assertIsInstance(suite, loader.suiteClass)
  100. expected = [loader.suiteClass([MyTestCase('test')])]
  101. self.assertEqual(list(suite), expected)
  102. # "This method searches `module` for classes derived from TestCase"
  103. #
  104. # What happens if no tests are found (no TestCase instances)?
  105. def test_loadTestsFromModule__no_TestCase_instances(self):
  106. m = types.ModuleType('m')
  107. loader = unittest.TestLoader()
  108. suite = loader.loadTestsFromModule(m)
  109. self.assertIsInstance(suite, loader.suiteClass)
  110. self.assertEqual(list(suite), [])
  111. # "This method searches `module` for classes derived from TestCase"
  112. #
  113. # What happens if no tests are found (TestCases instances, but no tests)?
  114. def test_loadTestsFromModule__no_TestCase_tests(self):
  115. m = types.ModuleType('m')
  116. class MyTestCase(unittest.TestCase):
  117. pass
  118. m.testcase_1 = MyTestCase
  119. loader = unittest.TestLoader()
  120. suite = loader.loadTestsFromModule(m)
  121. self.assertIsInstance(suite, loader.suiteClass)
  122. self.assertEqual(list(suite), [loader.suiteClass()])
  123. # "This method searches `module` for classes derived from TestCase"s
  124. #
  125. # What happens if loadTestsFromModule() is given something other
  126. # than a module?
  127. #
  128. # XXX Currently, it succeeds anyway. This flexibility
  129. # should either be documented or loadTestsFromModule() should
  130. # raise a TypeError
  131. #
  132. # XXX Certain people are using this behaviour. We'll add a test for it
  133. def test_loadTestsFromModule__not_a_module(self):
  134. class MyTestCase(unittest.TestCase):
  135. def test(self):
  136. pass
  137. class NotAModule(object):
  138. test_2 = MyTestCase
  139. loader = unittest.TestLoader()
  140. suite = loader.loadTestsFromModule(NotAModule)
  141. reference = [unittest.TestSuite([MyTestCase('test')])]
  142. self.assertEqual(list(suite), reference)
  143. # Check that loadTestsFromModule honors (or not) a module
  144. # with a load_tests function.
  145. @warningregistry
  146. def test_loadTestsFromModule__load_tests(self):
  147. m = types.ModuleType('m')
  148. class MyTestCase(unittest.TestCase):
  149. def test(self):
  150. pass
  151. m.testcase_1 = MyTestCase
  152. load_tests_args = []
  153. def load_tests(loader, tests, pattern):
  154. self.assertIsInstance(tests, unittest.TestSuite)
  155. load_tests_args.extend((loader, tests, pattern))
  156. return tests
  157. m.load_tests = load_tests
  158. loader = unittest.TestLoader()
  159. suite = loader.loadTestsFromModule(m)
  160. self.assertIsInstance(suite, unittest.TestSuite)
  161. self.assertEqual(load_tests_args, [loader, suite, None])
  162. # With Python 3.5, the undocumented and unofficial use_load_tests is
  163. # ignored (and deprecated).
  164. load_tests_args = []
  165. with warnings.catch_warnings(record=False):
  166. warnings.simplefilter('ignore')
  167. suite = loader.loadTestsFromModule(m, use_load_tests=False)
  168. self.assertEqual(load_tests_args, [loader, suite, None])
  169. @warningregistry
  170. def test_loadTestsFromModule__use_load_tests_deprecated_positional(self):
  171. m = types.ModuleType('m')
  172. class MyTestCase(unittest.TestCase):
  173. def test(self):
  174. pass
  175. m.testcase_1 = MyTestCase
  176. load_tests_args = []
  177. def load_tests(loader, tests, pattern):
  178. self.assertIsInstance(tests, unittest.TestSuite)
  179. load_tests_args.extend((loader, tests, pattern))
  180. return tests
  181. m.load_tests = load_tests
  182. # The method still works.
  183. loader = unittest.TestLoader()
  184. # use_load_tests=True as a positional argument.
  185. with warnings.catch_warnings(record=True) as w:
  186. warnings.simplefilter('always')
  187. suite = loader.loadTestsFromModule(m, False)
  188. self.assertIsInstance(suite, unittest.TestSuite)
  189. # load_tests was still called because use_load_tests is deprecated
  190. # and ignored.
  191. self.assertEqual(load_tests_args, [loader, suite, None])
  192. # We got a warning.
  193. self.assertIs(w[-1].category, DeprecationWarning)
  194. self.assertEqual(str(w[-1].message),
  195. 'use_load_tests is deprecated and ignored')
  196. @warningregistry
  197. def test_loadTestsFromModule__use_load_tests_deprecated_keyword(self):
  198. m = types.ModuleType('m')
  199. class MyTestCase(unittest.TestCase):
  200. def test(self):
  201. pass
  202. m.testcase_1 = MyTestCase
  203. load_tests_args = []
  204. def load_tests(loader, tests, pattern):
  205. self.assertIsInstance(tests, unittest.TestSuite)
  206. load_tests_args.extend((loader, tests, pattern))
  207. return tests
  208. m.load_tests = load_tests
  209. # The method still works.
  210. loader = unittest.TestLoader()
  211. with warnings.catch_warnings(record=True) as w:
  212. warnings.simplefilter('always')
  213. suite = loader.loadTestsFromModule(m, use_load_tests=False)
  214. self.assertIsInstance(suite, unittest.TestSuite)
  215. # load_tests was still called because use_load_tests is deprecated
  216. # and ignored.
  217. self.assertEqual(load_tests_args, [loader, suite, None])
  218. # We got a warning.
  219. self.assertIs(w[-1].category, DeprecationWarning)
  220. self.assertEqual(str(w[-1].message),
  221. 'use_load_tests is deprecated and ignored')
  222. @warningregistry
  223. def test_loadTestsFromModule__too_many_positional_args(self):
  224. m = types.ModuleType('m')
  225. class MyTestCase(unittest.TestCase):
  226. def test(self):
  227. pass
  228. m.testcase_1 = MyTestCase
  229. load_tests_args = []
  230. def load_tests(loader, tests, pattern):
  231. self.assertIsInstance(tests, unittest.TestSuite)
  232. load_tests_args.extend((loader, tests, pattern))
  233. return tests
  234. m.load_tests = load_tests
  235. loader = unittest.TestLoader()
  236. with self.assertRaises(TypeError) as cm, \
  237. warnings.catch_warnings(record=True) as w:
  238. warnings.simplefilter('always')
  239. loader.loadTestsFromModule(m, False, 'testme.*')
  240. # We still got the deprecation warning.
  241. self.assertIs(w[-1].category, DeprecationWarning)
  242. self.assertEqual(str(w[-1].message),
  243. 'use_load_tests is deprecated and ignored')
  244. # We also got a TypeError for too many positional arguments.
  245. self.assertEqual(type(cm.exception), TypeError)
  246. self.assertEqual(
  247. str(cm.exception),
  248. 'loadTestsFromModule() takes 1 positional argument but 3 were given')
  249. @warningregistry
  250. def test_loadTestsFromModule__use_load_tests_other_bad_keyword(self):
  251. m = types.ModuleType('m')
  252. class MyTestCase(unittest.TestCase):
  253. def test(self):
  254. pass
  255. m.testcase_1 = MyTestCase
  256. load_tests_args = []
  257. def load_tests(loader, tests, pattern):
  258. self.assertIsInstance(tests, unittest.TestSuite)
  259. load_tests_args.extend((loader, tests, pattern))
  260. return tests
  261. m.load_tests = load_tests
  262. loader = unittest.TestLoader()
  263. with warnings.catch_warnings():
  264. warnings.simplefilter('ignore')
  265. with self.assertRaises(TypeError) as cm:
  266. loader.loadTestsFromModule(
  267. m, use_load_tests=False, very_bad=True, worse=False)
  268. self.assertEqual(type(cm.exception), TypeError)
  269. # The error message names the first bad argument alphabetically,
  270. # however use_load_tests (which sorts first) is ignored.
  271. self.assertEqual(
  272. str(cm.exception),
  273. "loadTestsFromModule() got an unexpected keyword argument 'very_bad'")
  274. def test_loadTestsFromModule__pattern(self):
  275. m = types.ModuleType('m')
  276. class MyTestCase(unittest.TestCase):
  277. def test(self):
  278. pass
  279. m.testcase_1 = MyTestCase
  280. load_tests_args = []
  281. def load_tests(loader, tests, pattern):
  282. self.assertIsInstance(tests, unittest.TestSuite)
  283. load_tests_args.extend((loader, tests, pattern))
  284. return tests
  285. m.load_tests = load_tests
  286. loader = unittest.TestLoader()
  287. suite = loader.loadTestsFromModule(m, pattern='testme.*')
  288. self.assertIsInstance(suite, unittest.TestSuite)
  289. self.assertEqual(load_tests_args, [loader, suite, 'testme.*'])
  290. def test_loadTestsFromModule__faulty_load_tests(self):
  291. m = types.ModuleType('m')
  292. def load_tests(loader, tests, pattern):
  293. raise TypeError('some failure')
  294. m.load_tests = load_tests
  295. loader = unittest.TestLoader()
  296. suite = loader.loadTestsFromModule(m)
  297. self.assertIsInstance(suite, unittest.TestSuite)
  298. self.assertEqual(suite.countTestCases(), 1)
  299. # Errors loading the suite are also captured for introspection.
  300. self.assertNotEqual([], loader.errors)
  301. self.assertEqual(1, len(loader.errors))
  302. error = loader.errors[0]
  303. self.assertTrue(
  304. 'Failed to call load_tests:' in error,
  305. 'missing error string in %r' % error)
  306. test = list(suite)[0]
  307. self.assertRaisesRegex(TypeError, "some failure", test.m)
  308. ################################################################
  309. ### /Tests for TestLoader.loadTestsFromModule()
  310. ### Tests for TestLoader.loadTestsFromName()
  311. ################################################################
  312. # "The specifier name is a ``dotted name'' that may resolve either to
  313. # a module, a test case class, a TestSuite instance, a test method
  314. # within a test case class, or a callable object which returns a
  315. # TestCase or TestSuite instance."
  316. #
  317. # Is ValueError raised in response to an empty name?
  318. def test_loadTestsFromName__empty_name(self):
  319. loader = unittest.TestLoader()
  320. try:
  321. loader.loadTestsFromName('')
  322. except ValueError as e:
  323. self.assertEqual(str(e), "Empty module name")
  324. else:
  325. self.fail("TestLoader.loadTestsFromName failed to raise ValueError")
  326. # "The specifier name is a ``dotted name'' that may resolve either to
  327. # a module, a test case class, a TestSuite instance, a test method
  328. # within a test case class, or a callable object which returns a
  329. # TestCase or TestSuite instance."
  330. #
  331. # What happens when the name contains invalid characters?
  332. def test_loadTestsFromName__malformed_name(self):
  333. loader = unittest.TestLoader()
  334. suite = loader.loadTestsFromName('abc () //')
  335. error, test = self.check_deferred_error(loader, suite)
  336. expected = "Failed to import test module: abc () //"
  337. expected_regex = r"Failed to import test module: abc \(\) //"
  338. self.assertIn(
  339. expected, error,
  340. 'missing error string in %r' % error)
  341. self.assertRaisesRegex(
  342. ImportError, expected_regex, getattr(test, 'abc () //'))
  343. # "The specifier name is a ``dotted name'' that may resolve ... to a
  344. # module"
  345. #
  346. # What happens when a module by that name can't be found?
  347. def test_loadTestsFromName__unknown_module_name(self):
  348. loader = unittest.TestLoader()
  349. suite = loader.loadTestsFromName('sdasfasfasdf')
  350. expected = "No module named 'sdasfasfasdf'"
  351. error, test = self.check_deferred_error(loader, suite)
  352. self.assertIn(
  353. expected, error,
  354. 'missing error string in %r' % error)
  355. self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf)
  356. # "The specifier name is a ``dotted name'' that may resolve either to
  357. # a module, a test case class, a TestSuite instance, a test method
  358. # within a test case class, or a callable object which returns a
  359. # TestCase or TestSuite instance."
  360. #
  361. # What happens when the module is found, but the attribute isn't?
  362. def test_loadTestsFromName__unknown_attr_name_on_module(self):
  363. loader = unittest.TestLoader()
  364. suite = loader.loadTestsFromName('unittest.loader.sdasfasfasdf')
  365. expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'"
  366. error, test = self.check_deferred_error(loader, suite)
  367. self.assertIn(
  368. expected, error,
  369. 'missing error string in %r' % error)
  370. self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf)
  371. # "The specifier name is a ``dotted name'' that may resolve either to
  372. # a module, a test case class, a TestSuite instance, a test method
  373. # within a test case class, or a callable object which returns a
  374. # TestCase or TestSuite instance."
  375. #
  376. # What happens when the module is found, but the attribute isn't?
  377. def test_loadTestsFromName__unknown_attr_name_on_package(self):
  378. loader = unittest.TestLoader()
  379. suite = loader.loadTestsFromName('unittest.sdasfasfasdf')
  380. expected = "No module named 'unittest.sdasfasfasdf'"
  381. error, test = self.check_deferred_error(loader, suite)
  382. self.assertIn(
  383. expected, error,
  384. 'missing error string in %r' % error)
  385. self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf)
  386. # "The specifier name is a ``dotted name'' that may resolve either to
  387. # a module, a test case class, a TestSuite instance, a test method
  388. # within a test case class, or a callable object which returns a
  389. # TestCase or TestSuite instance."
  390. #
  391. # What happens when we provide the module, but the attribute can't be
  392. # found?
  393. def test_loadTestsFromName__relative_unknown_name(self):
  394. loader = unittest.TestLoader()
  395. suite = loader.loadTestsFromName('sdasfasfasdf', unittest)
  396. expected = "module 'unittest' has no attribute 'sdasfasfasdf'"
  397. error, test = self.check_deferred_error(loader, suite)
  398. self.assertIn(
  399. expected, error,
  400. 'missing error string in %r' % error)
  401. self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf)
  402. # "The specifier name is a ``dotted name'' that may resolve either to
  403. # a module, a test case class, a TestSuite instance, a test method
  404. # within a test case class, or a callable object which returns a
  405. # TestCase or TestSuite instance."
  406. # ...
  407. # "The method optionally resolves name relative to the given module"
  408. #
  409. # Does loadTestsFromName raise ValueError when passed an empty
  410. # name relative to a provided module?
  411. #
  412. # XXX Should probably raise a ValueError instead of an AttributeError
  413. def test_loadTestsFromName__relative_empty_name(self):
  414. loader = unittest.TestLoader()
  415. suite = loader.loadTestsFromName('', unittest)
  416. error, test = self.check_deferred_error(loader, suite)
  417. expected = "has no attribute ''"
  418. self.assertIn(
  419. expected, error,
  420. 'missing error string in %r' % error)
  421. self.assertRaisesRegex(AttributeError, expected, getattr(test, ''))
  422. # "The specifier name is a ``dotted name'' that may resolve either to
  423. # a module, a test case class, a TestSuite instance, a test method
  424. # within a test case class, or a callable object which returns a
  425. # TestCase or TestSuite instance."
  426. # ...
  427. # "The method optionally resolves name relative to the given module"
  428. #
  429. # What happens when an impossible name is given, relative to the provided
  430. # `module`?
  431. def test_loadTestsFromName__relative_malformed_name(self):
  432. loader = unittest.TestLoader()
  433. # XXX Should this raise AttributeError or ValueError?
  434. suite = loader.loadTestsFromName('abc () //', unittest)
  435. error, test = self.check_deferred_error(loader, suite)
  436. expected = "module 'unittest' has no attribute 'abc () //'"
  437. expected_regex = r"module 'unittest' has no attribute 'abc \(\) //'"
  438. self.assertIn(
  439. expected, error,
  440. 'missing error string in %r' % error)
  441. self.assertRaisesRegex(
  442. AttributeError, expected_regex, getattr(test, 'abc () //'))
  443. # "The method optionally resolves name relative to the given module"
  444. #
  445. # Does loadTestsFromName raise TypeError when the `module` argument
  446. # isn't a module object?
  447. #
  448. # XXX Accepts the not-a-module object, ignoring the object's type
  449. # This should raise an exception or the method name should be changed
  450. #
  451. # XXX Some people are relying on this, so keep it for now
  452. def test_loadTestsFromName__relative_not_a_module(self):
  453. class MyTestCase(unittest.TestCase):
  454. def test(self):
  455. pass
  456. class NotAModule(object):
  457. test_2 = MyTestCase
  458. loader = unittest.TestLoader()
  459. suite = loader.loadTestsFromName('test_2', NotAModule)
  460. reference = [MyTestCase('test')]
  461. self.assertEqual(list(suite), reference)
  462. # "The specifier name is a ``dotted name'' that may resolve either to
  463. # a module, a test case class, a TestSuite instance, a test method
  464. # within a test case class, or a callable object which returns a
  465. # TestCase or TestSuite instance."
  466. #
  467. # Does it raise an exception if the name resolves to an invalid
  468. # object?
  469. def test_loadTestsFromName__relative_bad_object(self):
  470. m = types.ModuleType('m')
  471. m.testcase_1 = object()
  472. loader = unittest.TestLoader()
  473. try:
  474. loader.loadTestsFromName('testcase_1', m)
  475. except TypeError:
  476. pass
  477. else:
  478. self.fail("Should have raised TypeError")
  479. # "The specifier name is a ``dotted name'' that may
  480. # resolve either to ... a test case class"
  481. def test_loadTestsFromName__relative_TestCase_subclass(self):
  482. m = types.ModuleType('m')
  483. class MyTestCase(unittest.TestCase):
  484. def test(self):
  485. pass
  486. m.testcase_1 = MyTestCase
  487. loader = unittest.TestLoader()
  488. suite = loader.loadTestsFromName('testcase_1', m)
  489. self.assertIsInstance(suite, loader.suiteClass)
  490. self.assertEqual(list(suite), [MyTestCase('test')])
  491. # "The specifier name is a ``dotted name'' that may resolve either to
  492. # a module, a test case class, a TestSuite instance, a test method
  493. # within a test case class, or a callable object which returns a
  494. # TestCase or TestSuite instance."
  495. def test_loadTestsFromName__relative_TestSuite(self):
  496. m = types.ModuleType('m')
  497. class MyTestCase(unittest.TestCase):
  498. def test(self):
  499. pass
  500. m.testsuite = unittest.TestSuite([MyTestCase('test')])
  501. loader = unittest.TestLoader()
  502. suite = loader.loadTestsFromName('testsuite', m)
  503. self.assertIsInstance(suite, loader.suiteClass)
  504. self.assertEqual(list(suite), [MyTestCase('test')])
  505. # "The specifier name is a ``dotted name'' that may resolve ... to
  506. # ... a test method within a test case class"
  507. def test_loadTestsFromName__relative_testmethod(self):
  508. m = types.ModuleType('m')
  509. class MyTestCase(unittest.TestCase):
  510. def test(self):
  511. pass
  512. m.testcase_1 = MyTestCase
  513. loader = unittest.TestLoader()
  514. suite = loader.loadTestsFromName('testcase_1.test', m)
  515. self.assertIsInstance(suite, loader.suiteClass)
  516. self.assertEqual(list(suite), [MyTestCase('test')])
  517. # "The specifier name is a ``dotted name'' that may resolve either to
  518. # a module, a test case class, a TestSuite instance, a test method
  519. # within a test case class, or a callable object which returns a
  520. # TestCase or TestSuite instance."
  521. #
  522. # Does loadTestsFromName() raise the proper exception when trying to
  523. # resolve "a test method within a test case class" that doesn't exist
  524. # for the given name (relative to a provided module)?
  525. def test_loadTestsFromName__relative_invalid_testmethod(self):
  526. m = types.ModuleType('m')
  527. class MyTestCase(unittest.TestCase):
  528. def test(self):
  529. pass
  530. m.testcase_1 = MyTestCase
  531. loader = unittest.TestLoader()
  532. suite = loader.loadTestsFromName('testcase_1.testfoo', m)
  533. expected = "type object 'MyTestCase' has no attribute 'testfoo'"
  534. error, test = self.check_deferred_error(loader, suite)
  535. self.assertIn(
  536. expected, error,
  537. 'missing error string in %r' % error)
  538. self.assertRaisesRegex(AttributeError, expected, test.testfoo)
  539. # "The specifier name is a ``dotted name'' that may resolve ... to
  540. # ... a callable object which returns a ... TestSuite instance"
  541. def test_loadTestsFromName__callable__TestSuite(self):
  542. m = types.ModuleType('m')
  543. testcase_1 = unittest.FunctionTestCase(lambda: None)
  544. testcase_2 = unittest.FunctionTestCase(lambda: None)
  545. def return_TestSuite():
  546. return unittest.TestSuite([testcase_1, testcase_2])
  547. m.return_TestSuite = return_TestSuite
  548. loader = unittest.TestLoader()
  549. suite = loader.loadTestsFromName('return_TestSuite', m)
  550. self.assertIsInstance(suite, loader.suiteClass)
  551. self.assertEqual(list(suite), [testcase_1, testcase_2])
  552. # "The specifier name is a ``dotted name'' that may resolve ... to
  553. # ... a callable object which returns a TestCase ... instance"
  554. def test_loadTestsFromName__callable__TestCase_instance(self):
  555. m = types.ModuleType('m')
  556. testcase_1 = unittest.FunctionTestCase(lambda: None)
  557. def return_TestCase():
  558. return testcase_1
  559. m.return_TestCase = return_TestCase
  560. loader = unittest.TestLoader()
  561. suite = loader.loadTestsFromName('return_TestCase', m)
  562. self.assertIsInstance(suite, loader.suiteClass)
  563. self.assertEqual(list(suite), [testcase_1])
  564. # "The specifier name is a ``dotted name'' that may resolve ... to
  565. # ... a callable object which returns a TestCase ... instance"
  566. #*****************************************************************
  567. #Override the suiteClass attribute to ensure that the suiteClass
  568. #attribute is used
  569. def test_loadTestsFromName__callable__TestCase_instance_ProperSuiteClass(self):
  570. class SubTestSuite(unittest.TestSuite):
  571. pass
  572. m = types.ModuleType('m')
  573. testcase_1 = unittest.FunctionTestCase(lambda: None)
  574. def return_TestCase():
  575. return testcase_1
  576. m.return_TestCase = return_TestCase
  577. loader = unittest.TestLoader()
  578. loader.suiteClass = SubTestSuite
  579. suite = loader.loadTestsFromName('return_TestCase', m)
  580. self.assertIsInstance(suite, loader.suiteClass)
  581. self.assertEqual(list(suite), [testcase_1])
  582. # "The specifier name is a ``dotted name'' that may resolve ... to
  583. # ... a test method within a test case class"
  584. #*****************************************************************
  585. #Override the suiteClass attribute to ensure that the suiteClass
  586. #attribute is used
  587. def test_loadTestsFromName__relative_testmethod_ProperSuiteClass(self):
  588. class SubTestSuite(unittest.TestSuite):
  589. pass
  590. m = types.ModuleType('m')
  591. class MyTestCase(unittest.TestCase):
  592. def test(self):
  593. pass
  594. m.testcase_1 = MyTestCase
  595. loader = unittest.TestLoader()
  596. loader.suiteClass=SubTestSuite
  597. suite = loader.loadTestsFromName('testcase_1.test', m)
  598. self.assertIsInstance(suite, loader.suiteClass)
  599. self.assertEqual(list(suite), [MyTestCase('test')])
  600. # "The specifier name is a ``dotted name'' that may resolve ... to
  601. # ... a callable object which returns a TestCase or TestSuite instance"
  602. #
  603. # What happens if the callable returns something else?
  604. def test_loadTestsFromName__callable__wrong_type(self):
  605. m = types.ModuleType('m')
  606. def return_wrong():
  607. return 6
  608. m.return_wrong = return_wrong
  609. loader = unittest.TestLoader()
  610. try:
  611. suite = loader.loadTestsFromName('return_wrong', m)
  612. except TypeError:
  613. pass
  614. else:
  615. self.fail("TestLoader.loadTestsFromName failed to raise TypeError")
  616. # "The specifier can refer to modules and packages which have not been
  617. # imported; they will be imported as a side-effect"
  618. def test_loadTestsFromName__module_not_loaded(self):
  619. # We're going to try to load this module as a side-effect, so it
  620. # better not be loaded before we try.
  621. #
  622. module_name = 'unittest.test.dummy'
  623. sys.modules.pop(module_name, None)
  624. loader = unittest.TestLoader()
  625. try:
  626. suite = loader.loadTestsFromName(module_name)
  627. self.assertIsInstance(suite, loader.suiteClass)
  628. self.assertEqual(list(suite), [])
  629. # module should now be loaded, thanks to loadTestsFromName()
  630. self.assertIn(module_name, sys.modules)
  631. finally:
  632. if module_name in sys.modules:
  633. del sys.modules[module_name]
  634. ################################################################
  635. ### Tests for TestLoader.loadTestsFromName()
  636. ### Tests for TestLoader.loadTestsFromNames()
  637. ################################################################
  638. def check_deferred_error(self, loader, suite):
  639. """Helper function for checking that errors in loading are reported.
  640. :param loader: A loader with some errors.
  641. :param suite: A suite that should have a late bound error.
  642. :return: The first error message from the loader and the test object
  643. from the suite.
  644. """
  645. self.assertIsInstance(suite, unittest.TestSuite)
  646. self.assertEqual(suite.countTestCases(), 1)
  647. # Errors loading the suite are also captured for introspection.
  648. self.assertNotEqual([], loader.errors)
  649. self.assertEqual(1, len(loader.errors))
  650. error = loader.errors[0]
  651. test = list(suite)[0]
  652. return error, test
  653. # "Similar to loadTestsFromName(), but takes a sequence of names rather
  654. # than a single name."
  655. #
  656. # What happens if that sequence of names is empty?
  657. def test_loadTestsFromNames__empty_name_list(self):
  658. loader = unittest.TestLoader()
  659. suite = loader.loadTestsFromNames([])
  660. self.assertIsInstance(suite, loader.suiteClass)
  661. self.assertEqual(list(suite), [])
  662. # "Similar to loadTestsFromName(), but takes a sequence of names rather
  663. # than a single name."
  664. # ...
  665. # "The method optionally resolves name relative to the given module"
  666. #
  667. # What happens if that sequence of names is empty?
  668. #
  669. # XXX Should this raise a ValueError or just return an empty TestSuite?
  670. def test_loadTestsFromNames__relative_empty_name_list(self):
  671. loader = unittest.TestLoader()
  672. suite = loader.loadTestsFromNames([], unittest)
  673. self.assertIsInstance(suite, loader.suiteClass)
  674. self.assertEqual(list(suite), [])
  675. # "The specifier name is a ``dotted name'' that may resolve either to
  676. # a module, a test case class, a TestSuite instance, a test method
  677. # within a test case class, or a callable object which returns a
  678. # TestCase or TestSuite instance."
  679. #
  680. # Is ValueError raised in response to an empty name?
  681. def test_loadTestsFromNames__empty_name(self):
  682. loader = unittest.TestLoader()
  683. try:
  684. loader.loadTestsFromNames([''])
  685. except ValueError as e:
  686. self.assertEqual(str(e), "Empty module name")
  687. else:
  688. self.fail("TestLoader.loadTestsFromNames failed to raise ValueError")
  689. # "The specifier name is a ``dotted name'' that may resolve either to
  690. # a module, a test case class, a TestSuite instance, a test method
  691. # within a test case class, or a callable object which returns a
  692. # TestCase or TestSuite instance."
  693. #
  694. # What happens when presented with an impossible module name?
  695. def test_loadTestsFromNames__malformed_name(self):
  696. loader = unittest.TestLoader()
  697. # XXX Should this raise ValueError or ImportError?
  698. suite = loader.loadTestsFromNames(['abc () //'])
  699. error, test = self.check_deferred_error(loader, list(suite)[0])
  700. expected = "Failed to import test module: abc () //"
  701. expected_regex = r"Failed to import test module: abc \(\) //"
  702. self.assertIn(
  703. expected, error,
  704. 'missing error string in %r' % error)
  705. self.assertRaisesRegex(
  706. ImportError, expected_regex, getattr(test, 'abc () //'))
  707. # "The specifier name is a ``dotted name'' that may resolve either to
  708. # a module, a test case class, a TestSuite instance, a test method
  709. # within a test case class, or a callable object which returns a
  710. # TestCase or TestSuite instance."
  711. #
  712. # What happens when no module can be found for the given name?
  713. def test_loadTestsFromNames__unknown_module_name(self):
  714. loader = unittest.TestLoader()
  715. suite = loader.loadTestsFromNames(['sdasfasfasdf'])
  716. error, test = self.check_deferred_error(loader, list(suite)[0])
  717. expected = "Failed to import test module: sdasfasfasdf"
  718. self.assertIn(
  719. expected, error,
  720. 'missing error string in %r' % error)
  721. self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf)
  722. # "The specifier name is a ``dotted name'' that may resolve either to
  723. # a module, a test case class, a TestSuite instance, a test method
  724. # within a test case class, or a callable object which returns a
  725. # TestCase or TestSuite instance."
  726. #
  727. # What happens when the module can be found, but not the attribute?
  728. def test_loadTestsFromNames__unknown_attr_name(self):
  729. loader = unittest.TestLoader()
  730. suite = loader.loadTestsFromNames(
  731. ['unittest.loader.sdasfasfasdf', 'unittest.test.dummy'])
  732. error, test = self.check_deferred_error(loader, list(suite)[0])
  733. expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'"
  734. self.assertIn(
  735. expected, error,
  736. 'missing error string in %r' % error)
  737. self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf)
  738. # "The specifier name is a ``dotted name'' that may resolve either to
  739. # a module, a test case class, a TestSuite instance, a test method
  740. # within a test case class, or a callable object which returns a
  741. # TestCase or TestSuite instance."
  742. # ...
  743. # "The method optionally resolves name relative to the given module"
  744. #
  745. # What happens when given an unknown attribute on a specified `module`
  746. # argument?
  747. def test_loadTestsFromNames__unknown_name_relative_1(self):
  748. loader = unittest.TestLoader()
  749. suite = loader.loadTestsFromNames(['sdasfasfasdf'], unittest)
  750. error, test = self.check_deferred_error(loader, list(suite)[0])
  751. expected = "module 'unittest' has no attribute 'sdasfasfasdf'"
  752. self.assertIn(
  753. expected, error,
  754. 'missing error string in %r' % error)
  755. self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf)
  756. # "The specifier name is a ``dotted name'' that may resolve either to
  757. # a module, a test case class, a TestSuite instance, a test method
  758. # within a test case class, or a callable object which returns a
  759. # TestCase or TestSuite instance."
  760. # ...
  761. # "The method optionally resolves name relative to the given module"
  762. #
  763. # Do unknown attributes (relative to a provided module) still raise an
  764. # exception even in the presence of valid attribute names?
  765. def test_loadTestsFromNames__unknown_name_relative_2(self):
  766. loader = unittest.TestLoader()
  767. suite = loader.loadTestsFromNames(['TestCase', 'sdasfasfasdf'], unittest)
  768. error, test = self.check_deferred_error(loader, list(suite)[1])
  769. expected = "module 'unittest' has no attribute 'sdasfasfasdf'"
  770. self.assertIn(
  771. expected, error,
  772. 'missing error string in %r' % error)
  773. self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf)
  774. # "The specifier name is a ``dotted name'' that may resolve either to
  775. # a module, a test case class, a TestSuite instance, a test method
  776. # within a test case class, or a callable object which returns a
  777. # TestCase or TestSuite instance."
  778. # ...
  779. # "The method optionally resolves name relative to the given module"
  780. #
  781. # What happens when faced with the empty string?
  782. #
  783. # XXX This currently raises AttributeError, though ValueError is probably
  784. # more appropriate
  785. def test_loadTestsFromNames__relative_empty_name(self):
  786. loader = unittest.TestLoader()
  787. suite = loader.loadTestsFromNames([''], unittest)
  788. error, test = self.check_deferred_error(loader, list(suite)[0])
  789. expected = "has no attribute ''"
  790. self.assertIn(
  791. expected, error,
  792. 'missing error string in %r' % error)
  793. self.assertRaisesRegex(AttributeError, expected, getattr(test, ''))
  794. # "The specifier name is a ``dotted name'' that may resolve either to
  795. # a module, a test case class, a TestSuite instance, a test method
  796. # within a test case class, or a callable object which returns a
  797. # TestCase or TestSuite instance."
  798. # ...
  799. # "The method optionally resolves name relative to the given module"
  800. #
  801. # What happens when presented with an impossible attribute name?
  802. def test_loadTestsFromNames__relative_malformed_name(self):
  803. loader = unittest.TestLoader()
  804. # XXX Should this raise AttributeError or ValueError?
  805. suite = loader.loadTestsFromNames(['abc () //'], unittest)
  806. error, test = self.check_deferred_error(loader, list(suite)[0])
  807. expected = "module 'unittest' has no attribute 'abc () //'"
  808. expected_regex = r"module 'unittest' has no attribute 'abc \(\) //'"
  809. self.assertIn(
  810. expected, error,
  811. 'missing error string in %r' % error)
  812. self.assertRaisesRegex(
  813. AttributeError, expected_regex, getattr(test, 'abc () //'))
  814. # "The method optionally resolves name relative to the given module"
  815. #
  816. # Does loadTestsFromNames() make sure the provided `module` is in fact
  817. # a module?
  818. #
  819. # XXX This validation is currently not done. This flexibility should
  820. # either be documented or a TypeError should be raised.
  821. def test_loadTestsFromNames__relative_not_a_module(self):
  822. class MyTestCase(unittest.TestCase):
  823. def test(self):
  824. pass
  825. class NotAModule(object):
  826. test_2 = MyTestCase
  827. loader = unittest.TestLoader()
  828. suite = loader.loadTestsFromNames(['test_2'], NotAModule)
  829. reference = [unittest.TestSuite([MyTestCase('test')])]
  830. self.assertEqual(list(suite), reference)
  831. # "The specifier name is a ``dotted name'' that may resolve either to
  832. # a module, a test case class, a TestSuite instance, a test method
  833. # within a test case class, or a callable object which returns a
  834. # TestCase or TestSuite instance."
  835. #
  836. # Does it raise an exception if the name resolves to an invalid
  837. # object?
  838. def test_loadTestsFromNames__relative_bad_object(self):
  839. m = types.ModuleType('m')
  840. m.testcase_1 = object()
  841. loader = unittest.TestLoader()
  842. try:
  843. loader.loadTestsFromNames(['testcase_1'], m)
  844. except TypeError:
  845. pass
  846. else:
  847. self.fail("Should have raised TypeError")
  848. # "The specifier name is a ``dotted name'' that may resolve ... to
  849. # ... a test case class"
  850. def test_loadTestsFromNames__relative_TestCase_subclass(self):
  851. m = types.ModuleType('m')
  852. class MyTestCase(unittest.TestCase):
  853. def test(self):
  854. pass
  855. m.testcase_1 = MyTestCase
  856. loader = unittest.TestLoader()
  857. suite = loader.loadTestsFromNames(['testcase_1'], m)
  858. self.assertIsInstance(suite, loader.suiteClass)
  859. expected = loader.suiteClass([MyTestCase('test')])
  860. self.assertEqual(list(suite), [expected])
  861. # "The specifier name is a ``dotted name'' that may resolve ... to
  862. # ... a TestSuite instance"
  863. def test_loadTestsFromNames__relative_TestSuite(self):
  864. m = types.ModuleType('m')
  865. class MyTestCase(unittest.TestCase):
  866. def test(self):
  867. pass
  868. m.testsuite = unittest.TestSuite([MyTestCase('test')])
  869. loader = unittest.TestLoader()
  870. suite = loader.loadTestsFromNames(['testsuite'], m)
  871. self.assertIsInstance(suite, loader.suiteClass)
  872. self.assertEqual(list(suite), [m.testsuite])
  873. # "The specifier name is a ``dotted name'' that may resolve ... to ... a
  874. # test method within a test case class"
  875. def test_loadTestsFromNames__relative_testmethod(self):
  876. m = types.ModuleType('m')
  877. class MyTestCase(unittest.TestCase):
  878. def test(self):
  879. pass
  880. m.testcase_1 = MyTestCase
  881. loader = unittest.TestLoader()
  882. suite = loader.loadTestsFromNames(['testcase_1.test'], m)
  883. self.assertIsInstance(suite, loader.suiteClass)
  884. ref_suite = unittest.TestSuite([MyTestCase('test')])
  885. self.assertEqual(list(suite), [ref_suite])
  886. # #14971: Make sure the dotted name resolution works even if the actual
  887. # function doesn't have the same name as is used to find it.
  888. def test_loadTestsFromName__function_with_different_name_than_method(self):
  889. # lambdas have the name '<lambda>'.
  890. m = types.ModuleType('m')
  891. class MyTestCase(unittest.TestCase):
  892. test = lambda: 1
  893. m.testcase_1 = MyTestCase
  894. loader = unittest.TestLoader()
  895. suite = loader.loadTestsFromNames(['testcase_1.test'], m)
  896. self.assertIsInstance(suite, loader.suiteClass)
  897. ref_suite = unittest.TestSuite([MyTestCase('test')])
  898. self.assertEqual(list(suite), [ref_suite])
  899. # "The specifier name is a ``dotted name'' that may resolve ... to ... a
  900. # test method within a test case class"
  901. #
  902. # Does the method gracefully handle names that initially look like they
  903. # resolve to "a test method within a test case class" but don't?
  904. def test_loadTestsFromNames__relative_invalid_testmethod(self):
  905. m = types.ModuleType('m')
  906. class MyTestCase(unittest.TestCase):
  907. def test(self):
  908. pass
  909. m.testcase_1 = MyTestCase
  910. loader = unittest.TestLoader()
  911. suite = loader.loadTestsFromNames(['testcase_1.testfoo'], m)
  912. error, test = self.check_deferred_error(loader, list(suite)[0])
  913. expected = "type object 'MyTestCase' has no attribute 'testfoo'"
  914. self.assertIn(
  915. expected, error,
  916. 'missing error string in %r' % error)
  917. self.assertRaisesRegex(AttributeError, expected, test.testfoo)
  918. # "The specifier name is a ``dotted name'' that may resolve ... to
  919. # ... a callable object which returns a ... TestSuite instance"
  920. def test_loadTestsFromNames__callable__TestSuite(self):
  921. m = types.ModuleType('m')
  922. testcase_1 = unittest.FunctionTestCase(lambda: None)
  923. testcase_2 = unittest.FunctionTestCase(lambda: None)
  924. def return_TestSuite():
  925. return unittest.TestSuite([testcase_1, testcase_2])
  926. m.return_TestSuite = return_TestSuite
  927. loader = unittest.TestLoader()
  928. suite = loader.loadTestsFromNames(['return_TestSuite'], m)
  929. self.assertIsInstance(suite, loader.suiteClass)
  930. expected = unittest.TestSuite([testcase_1, testcase_2])
  931. self.assertEqual(list(suite), [expected])
  932. # "The specifier name is a ``dotted name'' that may resolve ... to
  933. # ... a callable object which returns a TestCase ... instance"
  934. def test_loadTestsFromNames__callable__TestCase_instance(self):
  935. m = types.ModuleType('m')
  936. testcase_1 = unittest.FunctionTestCase(lambda: None)
  937. def return_TestCase():
  938. return testcase_1
  939. m.return_TestCase = return_TestCase
  940. loader = unittest.TestLoader()
  941. suite = loader.loadTestsFromNames(['return_TestCase'], m)
  942. self.assertIsInstance(suite, loader.suiteClass)
  943. ref_suite = unittest.TestSuite([testcase_1])
  944. self.assertEqual(list(suite), [ref_suite])
  945. # "The specifier name is a ``dotted name'' that may resolve ... to
  946. # ... a callable object which returns a TestCase or TestSuite instance"
  947. #
  948. # Are staticmethods handled correctly?
  949. def test_loadTestsFromNames__callable__call_staticmethod(self):
  950. m = types.ModuleType('m')
  951. class Test1(unittest.TestCase):
  952. def test(self):
  953. pass
  954. testcase_1 = Test1('test')
  955. class Foo(unittest.TestCase):
  956. @staticmethod
  957. def foo():
  958. return testcase_1
  959. m.Foo = Foo
  960. loader = unittest.TestLoader()
  961. suite = loader.loadTestsFromNames(['Foo.foo'], m)
  962. self.assertIsInstance(suite, loader.suiteClass)
  963. ref_suite = unittest.TestSuite([testcase_1])
  964. self.assertEqual(list(suite), [ref_suite])
  965. # "The specifier name is a ``dotted name'' that may resolve ... to
  966. # ... a callable object which returns a TestCase or TestSuite instance"
  967. #
  968. # What happens when the callable returns something else?
  969. def test_loadTestsFromNames__callable__wrong_type(self):
  970. m = types.ModuleType('m')
  971. def return_wrong():
  972. return 6
  973. m.return_wrong = return_wrong
  974. loader = unittest.TestLoader()
  975. try:
  976. suite = loader.loadTestsFromNames(['return_wrong'], m)
  977. except TypeError:
  978. pass
  979. else:
  980. self.fail("TestLoader.loadTestsFromNames failed to raise TypeError")
  981. # "The specifier can refer to modules and packages which have not been
  982. # imported; they will be imported as a side-effect"
  983. def test_loadTestsFromNames__module_not_loaded(self):
  984. # We're going to try to load this module as a side-effect, so it
  985. # better not be loaded before we try.
  986. #
  987. module_name = 'unittest.test.dummy'
  988. sys.modules.pop(module_name, None)
  989. loader = unittest.TestLoader()
  990. try:
  991. suite = loader.loadTestsFromNames([module_name])
  992. self.assertIsInstance(suite, loader.suiteClass)
  993. self.assertEqual(list(suite), [unittest.TestSuite()])
  994. # module should now be loaded, thanks to loadTestsFromName()
  995. self.assertIn(module_name, sys.modules)
  996. finally:
  997. if module_name in sys.modules:
  998. del sys.modules[module_name]
  999. ################################################################
  1000. ### /Tests for TestLoader.loadTestsFromNames()
  1001. ### Tests for TestLoader.getTestCaseNames()
  1002. ################################################################
  1003. # "Return a sorted sequence of method names found within testCaseClass"
  1004. #
  1005. # Test.foobar is defined to make sure getTestCaseNames() respects
  1006. # loader.testMethodPrefix
  1007. def test_getTestCaseNames(self):
  1008. class Test(unittest.TestCase):
  1009. def test_1(self): pass
  1010. def test_2(self): pass
  1011. def foobar(self): pass
  1012. loader = unittest.TestLoader()
  1013. self.assertEqual(loader.getTestCaseNames(Test), ['test_1', 'test_2'])
  1014. # "Return a sorted sequence of method names found within testCaseClass"
  1015. #
  1016. # Does getTestCaseNames() behave appropriately if no tests are found?
  1017. def test_getTestCaseNames__no_tests(self):
  1018. class Test(unittest.TestCase):
  1019. def foobar(self): pass
  1020. loader = unittest.TestLoader()
  1021. self.assertEqual(loader.getTestCaseNames(Test), [])
  1022. # "Return a sorted sequence of method names found within testCaseClass"
  1023. #
  1024. # Are not-TestCases handled gracefully?
  1025. #
  1026. # XXX This should raise a TypeError, not return a list
  1027. #
  1028. # XXX It's too late in the 2.5 release cycle to fix this, but it should
  1029. # probably be revisited for 2.6
  1030. def test_getTestCaseNames__not_a_TestCase(self):
  1031. class BadCase(int):
  1032. def test_foo(self):
  1033. pass
  1034. loader = unittest.TestLoader()
  1035. names = loader.getTestCaseNames(BadCase)
  1036. self.assertEqual(names, ['test_foo'])
  1037. # "Return a sorted sequence of method names found within testCaseClass"
  1038. #
  1039. # Make sure inherited names are handled.
  1040. #
  1041. # TestP.foobar is defined to make sure getTestCaseNames() respects
  1042. # loader.testMethodPrefix
  1043. def test_getTestCaseNames__inheritance(self):
  1044. class TestP(unittest.TestCase):
  1045. def test_1(self): pass
  1046. def test_2(self): pass
  1047. def foobar(self): pass
  1048. class TestC(TestP):
  1049. def test_1(self): pass
  1050. def test_3(self): pass
  1051. loader = unittest.TestLoader()
  1052. names = ['test_1', 'test_2', 'test_3']
  1053. self.assertEqual(loader.getTestCaseNames(TestC), names)
  1054. # "Return a sorted sequence of method names found within testCaseClass"
  1055. #
  1056. # If TestLoader.testNamePatterns is set, only tests that match one of these
  1057. # patterns should be included.
  1058. def test_getTestCaseNames__testNamePatterns(self):
  1059. class MyTest(unittest.TestCase):
  1060. def test_1(self): pass
  1061. def test_2(self): pass
  1062. def foobar(self): pass
  1063. loader = unittest.TestLoader()
  1064. loader.testNamePatterns = []
  1065. self.assertEqual(loader.getTestCaseNames(MyTest), [])
  1066. loader.testNamePatterns = ['*1']
  1067. self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1'])
  1068. loader.testNamePatterns = ['*1', '*2']
  1069. self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1', 'test_2'])
  1070. loader.testNamePatterns = ['*My*']
  1071. self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1', 'test_2'])
  1072. loader.testNamePatterns = ['*my*']
  1073. self.assertEqual(loader.getTestCaseNames(MyTest), [])
  1074. # "Return a sorted sequence of method names found within testCaseClass"
  1075. #
  1076. # If TestLoader.testNamePatterns is set, only tests that match one of these
  1077. # patterns should be included.
  1078. #
  1079. # For backwards compatibility reasons (see bpo-32071), the check may only
  1080. # touch a TestCase's attribute if it starts with the test method prefix.
  1081. def test_getTestCaseNames__testNamePatterns__attribute_access_regression(self):
  1082. class Trap:
  1083. def __get__(*ignored):
  1084. self.fail('Non-test attribute accessed')
  1085. class MyTest(unittest.TestCase):
  1086. def test_1(self): pass
  1087. foobar = Trap()
  1088. loader = unittest.TestLoader()
  1089. self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1'])
  1090. loader = unittest.TestLoader()
  1091. loader.testNamePatterns = []
  1092. self.assertEqual(loader.getTestCaseNames(MyTest), [])
  1093. ################################################################
  1094. ### /Tests for TestLoader.getTestCaseNames()
  1095. ### Tests for TestLoader.testMethodPrefix
  1096. ################################################################
  1097. # "String giving the prefix of method names which will be interpreted as
  1098. # test methods"
  1099. #
  1100. # Implicit in the documentation is that testMethodPrefix is respected by
  1101. # all loadTestsFrom* methods.
  1102. def test_testMethodPrefix__loadTestsFromTestCase(self):
  1103. class Foo(unittest.TestCase):
  1104. def test_1(self): pass
  1105. def test_2(self): pass
  1106. def foo_bar(self): pass
  1107. tests_1 = unittest.TestSuite([Foo('foo_bar')])
  1108. tests_2 = unittest.TestSuite([Foo('test_1'), Foo('test_2')])
  1109. loader = unittest.TestLoader()
  1110. loader.testMethodPrefix = 'foo'
  1111. self.assertEqual(loader.loadTestsFromTestCase(Foo), tests_1)
  1112. loader.testMethodPrefix = 'test'
  1113. self.assertEqual(loader.loadTestsFromTestCase(Foo), tests_2)
  1114. # "String giving the prefix of method names which will be interpreted as
  1115. # test methods"
  1116. #
  1117. # Implicit in the documentation is that testMethodPrefix is respected by
  1118. # all loadTestsFrom* methods.
  1119. def test_testMethodPrefix__loadTestsFromModule(self):
  1120. m = types.ModuleType('m')
  1121. class Foo(unittest.TestCase):
  1122. def test_1(self): pass
  1123. def test_2(self): pass
  1124. def foo_bar(self): pass
  1125. m.Foo = Foo
  1126. tests_1 = [unittest.TestSuite([Foo('foo_bar')])]
  1127. tests_2 = [unittest.TestSuite([Foo('test_1'), Foo('test_2')])]
  1128. loader = unittest.TestLoader()
  1129. loader.testMethodPrefix = 'foo'
  1130. self.assertEqual(list(loader.loadTestsFromModule(m)), tests_1)
  1131. loader.testMethodPrefix = 'test'
  1132. self.assertEqual(list(loader.loadTestsFromModule(m)), tests_2)
  1133. # "String giving the prefix of method names which will be interpreted as
  1134. # test methods"
  1135. #
  1136. # Implicit in the documentation is that testMethodPrefix is respected by
  1137. # all loadTestsFrom* methods.
  1138. def test_testMethodPrefix__loadTestsFromName(self):
  1139. m = types.ModuleType('m')
  1140. class Foo(unittest.TestCase):
  1141. def test_1(self): pass
  1142. def test_2(self): pass
  1143. def foo_bar(self): pass
  1144. m.Foo = Foo
  1145. tests_1 = unittest.TestSuite([Foo('foo_bar')])
  1146. tests_2 = unittest.TestSuite([Foo('test_1'), Foo('test_2')])
  1147. loader = unittest.TestLoader()
  1148. loader.testMethodPrefix = 'foo'
  1149. self.assertEqual(loader.loadTestsFromName('Foo', m), tests_1)
  1150. loader.testMethodPrefix = 'test'
  1151. self.assertEqual(loader.loadTestsFromName('Foo', m), tests_2)
  1152. # "String giving the prefix of method names which will be interpreted as
  1153. # test methods"
  1154. #
  1155. # Implicit in the documentation is that testMethodPrefix is respected by
  1156. # all loadTestsFrom* methods.
  1157. def test_testMethodPrefix__loadTestsFromNames(self):
  1158. m = types.ModuleType('m')
  1159. class Foo(unittest.TestCase):
  1160. def test_1(self): pass
  1161. def test_2(self): pass
  1162. def foo_bar(self): pass
  1163. m.Foo = Foo
  1164. tests_1 = unittest.TestSuite([unittest.TestSuite([Foo('foo_bar')])])
  1165. tests_2 = unittest.TestSuite([Foo('test_1'), Foo('test_2')])
  1166. tests_2 = unittest.TestSuite([tests_2])
  1167. loader = unittest.TestLoader()
  1168. loader.testMethodPrefix = 'foo'
  1169. self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests_1)
  1170. loader.testMethodPrefix = 'test'
  1171. self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests_2)
  1172. # "The default value is 'test'"
  1173. def test_testMethodPrefix__default_value(self):
  1174. loader = unittest.TestLoader()
  1175. self.assertEqual(loader.testMethodPrefix, 'test')
  1176. ################################################################
  1177. ### /Tests for TestLoader.testMethodPrefix
  1178. ### Tests for TestLoader.sortTestMethodsUsing
  1179. ################################################################
  1180. # "Function to be used to compare method names when sorting them in
  1181. # getTestCaseNames() and all the loadTestsFromX() methods"
  1182. def test_sortTestMethodsUsing__loadTestsFromTestCase(self):
  1183. def reversed_cmp(x, y):
  1184. return -((x > y) - (x < y))
  1185. class Foo(unittest.TestCase):
  1186. def test_1(self): pass
  1187. def test_2(self): pass
  1188. loader = unittest.TestLoader()
  1189. loader.sortTestMethodsUsing = reversed_cmp
  1190. tests = loader.suiteClass([Foo('test_2'), Foo('test_1')])
  1191. self.assertEqual(loader.loadTestsFromTestCase(Foo), tests)
  1192. # "Function to be used to compare method names when sorting them in
  1193. # getTestCaseNames() and all the loadTestsFromX() methods"
  1194. def test_sortTestMethodsUsing__loadTestsFromModule(self):
  1195. def reversed_cmp(x, y):
  1196. return -((x > y) - (x < y))
  1197. m = types.ModuleType('m')
  1198. class Foo(unittest.TestCase):
  1199. def test_1(self): pass
  1200. def test_2(self): pass
  1201. m.Foo = Foo
  1202. loader = unittest.TestLoader()
  1203. loader.sortTestMethodsUsing = reversed_cmp
  1204. tests = [loader.suiteClass([Foo('test_2'), Foo('test_1')])]
  1205. self.assertEqual(list(loader.loadTestsFromModule(m)), tests)
  1206. # "Function to be used to compare method names when sorting them in
  1207. # getTestCaseNames() and all the loadTestsFromX() methods"
  1208. def test_sortTestMethodsUsing__loadTestsFromName(self):
  1209. def reversed_cmp(x, y):
  1210. return -((x > y) - (x < y))
  1211. m = types.ModuleType('m')
  1212. class Foo(unittest.TestCase):
  1213. def test_1(self): pass
  1214. def test_2(self): pass
  1215. m.Foo = Foo
  1216. loader = unittest.TestLoader()
  1217. loader.sortTestMethodsUsing = reversed_cmp
  1218. tests = loader.suiteClass([Foo('test_2'), Foo('test_1')])
  1219. self.assertEqual(loader.loadTestsFromName('Foo', m), tests)
  1220. # "Function to be used to compare method names when sorting them in
  1221. # getTestCaseNames() and all the loadTestsFromX() methods"
  1222. def test_sortTestMethodsUsing__loadTestsFromNames(self):
  1223. def reversed_cmp(x, y):
  1224. return -((x > y) - (x < y))
  1225. m = types.ModuleType('m')
  1226. class Foo(unittest.TestCase):
  1227. def test_1(self): pass
  1228. def test_2(self): pass
  1229. m.Foo = Foo
  1230. loader = unittest.TestLoader()
  1231. loader.sortTestMethodsUsing = reversed_cmp
  1232. tests = [loader.suiteClass([Foo('test_2'), Foo('test_1')])]
  1233. self.assertEqual(list(loader.loadTestsFromNames(['Foo'], m)), tests)
  1234. # "Function to be used to compare method names when sorting them in
  1235. # getTestCaseNames()"
  1236. #
  1237. # Does it actually affect getTestCaseNames()?
  1238. def test_sortTestMethodsUsing__getTestCaseNames(self):
  1239. def reversed_cmp(x, y):
  1240. return -((x > y) - (x < y))
  1241. class Foo(unittest.TestCase):
  1242. def test_1(self): pass
  1243. def test_2(self): pass
  1244. loader = unittest.TestLoader()
  1245. loader.sortTestMethodsUsing = reversed_cmp
  1246. test_names = ['test_2', 'test_1']
  1247. self.assertEqual(loader.getTestCaseNames(Foo), test_names)
  1248. # "The default value is the built-in cmp() function"
  1249. # Since cmp is now defunct, we simply verify that the results
  1250. # occur in the same order as they would with the default sort.
  1251. def test_sortTestMethodsUsing__default_value(self):
  1252. loader = unittest.TestLoader()
  1253. class Foo(unittest.TestCase):
  1254. def test_2(self): pass
  1255. def test_3(self): pass
  1256. def test_1(self): pass
  1257. test_names = ['test_2', 'test_3', 'test_1']
  1258. self.assertEqual(loader.getTestCaseNames(Foo), sorted(test_names))
  1259. # "it can be set to None to disable the sort."
  1260. #
  1261. # XXX How is this different from reassigning cmp? Are the tests returned
  1262. # in a random order or something? This behaviour should die
  1263. def test_sortTestMethodsUsing__None(self):
  1264. class Foo(unittest.TestCase):
  1265. def test_1(self): pass
  1266. def test_2(self): pass
  1267. loader = unittest.TestLoader()
  1268. loader.sortTestMethodsUsing = None
  1269. test_names = ['test_2', 'test_1']
  1270. self.assertEqual(set(loader.getTestCaseNames(Foo)), set(test_names))
  1271. ################################################################
  1272. ### /Tests for TestLoader.sortTestMethodsUsing
  1273. ### Tests for TestLoader.suiteClass
  1274. ################################################################
  1275. # "Callable object that constructs a test suite from a list of tests."
  1276. def test_suiteClass__loadTestsFromTestCase(self):
  1277. class Foo(unittest.TestCase):
  1278. def test_1(self): pass
  1279. def test_2(self): pass
  1280. def foo_bar(self): pass
  1281. tests = [Foo('test_1'), Foo('test_2')]
  1282. loader = unittest.TestLoader()
  1283. loader.suiteClass = list
  1284. self.assertEqual(loader.loadTestsFromTestCase(Foo), tests)
  1285. # It is implicit in the documentation for TestLoader.suiteClass that
  1286. # all TestLoader.loadTestsFrom* methods respect it. Let's make sure
  1287. def test_suiteClass__loadTestsFromModule(self):
  1288. m = types.ModuleType('m')
  1289. class Foo(unittest.TestCase):
  1290. def test_1(self): pass
  1291. def test_2(self): pass
  1292. def foo_bar(self): pass
  1293. m.Foo = Foo
  1294. tests = [[Foo('test_1'), Foo('test_2')]]
  1295. loader = unittest.TestLoader()
  1296. loader.suiteClass = list
  1297. self.assertEqual(loader.loadTestsFromModule(m), tests)
  1298. # It is implicit in the documentation for TestLoader.suiteClass that
  1299. # all TestLoader.loadTestsFrom* methods respect it. Let's make sure
  1300. def test_suiteClass__loadTestsFromName(self):
  1301. m = types.ModuleType('m')
  1302. class Foo(unittest.TestCase):
  1303. def test_1(self): pass
  1304. def test_2(self): pass
  1305. def foo_bar(self): pass
  1306. m.Foo = Foo
  1307. tests = [Foo('test_1'), Foo('test_2')]
  1308. loader = unittest.TestLoader()
  1309. loader.suiteClass = list
  1310. self.assertEqual(loader.loadTestsFromName('Foo', m), tests)
  1311. # It is implicit in the documentation for TestLoader.suiteClass that
  1312. # all TestLoader.loadTestsFrom* methods respect it. Let's make sure
  1313. def test_suiteClass__loadTestsFromNames(self):
  1314. m = types.ModuleType('m')
  1315. class Foo(unittest.TestCase):
  1316. def test_1(self): pass
  1317. def test_2(self): pass
  1318. def foo_bar(self): pass
  1319. m.Foo = Foo
  1320. tests = [[Foo('test_1'), Foo('test_2')]]
  1321. loader = unittest.TestLoader()
  1322. loader.suiteClass = list
  1323. self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests)
  1324. # "The default value is the TestSuite class"
  1325. def test_suiteClass__default_value(self):
  1326. loader = unittest.TestLoader()
  1327. self.assertIs(loader.suiteClass, unittest.TestSuite)
  1328. def test_partial_functions(self):
  1329. def noop(arg):
  1330. pass
  1331. class Foo(unittest.TestCase):
  1332. pass
  1333. setattr(Foo, 'test_partial', functools.partial(noop, None))
  1334. loader = unittest.TestLoader()
  1335. test_names = ['test_partial']
  1336. self.assertEqual(loader.getTestCaseNames(Foo), test_names)
  1337. class TestObsoleteFunctions(unittest.TestCase):
  1338. class MyTestSuite(unittest.TestSuite):
  1339. pass
  1340. class MyTestCase(unittest.TestCase):
  1341. def check_1(self): pass
  1342. def check_2(self): pass
  1343. def test(self): pass
  1344. @staticmethod
  1345. def reverse_three_way_cmp(a, b):
  1346. return unittest.util.three_way_cmp(b, a)
  1347. def test_getTestCaseNames(self):
  1348. with self.assertWarns(DeprecationWarning) as w:
  1349. tests = unittest.getTestCaseNames(self.MyTestCase,
  1350. prefix='check', sortUsing=self.reverse_three_way_cmp,
  1351. testNamePatterns=None)
  1352. self.assertEqual(w.filename, __file__)
  1353. self.assertEqual(tests, ['check_2', 'check_1'])
  1354. def test_makeSuite(self):
  1355. with self.assertWarns(DeprecationWarning) as w:
  1356. suite = unittest.makeSuite(self.MyTestCase,
  1357. prefix='check', sortUsing=self.reverse_three_way_cmp,
  1358. suiteClass=self.MyTestSuite)
  1359. self.assertEqual(w.filename, __file__)
  1360. self.assertIsInstance(suite, self.MyTestSuite)
  1361. expected = self.MyTestSuite([self.MyTestCase('check_2'),
  1362. self.MyTestCase('check_1')])
  1363. self.assertEqual(suite, expected)
  1364. def test_findTestCases(self):
  1365. m = types.ModuleType('m')
  1366. m.testcase_1 = self.MyTestCase
  1367. with self.assertWarns(DeprecationWarning) as w:
  1368. suite = unittest.findTestCases(m,
  1369. prefix='check', sortUsing=self.reverse_three_way_cmp,
  1370. suiteClass=self.MyTestSuite)
  1371. self.assertEqual(w.filename, __file__)
  1372. self.assertIsInstance(suite, self.MyTestSuite)
  1373. expected = [self.MyTestSuite([self.MyTestCase('check_2'),
  1374. self.MyTestCase('check_1')])]
  1375. self.assertEqual(list(suite), expected)
  1376. if __name__ == "__main__":
  1377. unittest.main()