python (3.12.0)
1 import os
2 import sys
3 import subprocess
4 from test import support
5 import unittest
6 import test.test_unittest
7 from test.test_unittest.test_result import BufferedWriter
8
9
10 class ESC[4;38;5;81mTest_TestProgram(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
11
12 def test_discovery_from_dotted_path(self):
13 loader = unittest.TestLoader()
14
15 tests = [self]
16 expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__))
17
18 self.wasRun = False
19 def _find_tests(start_dir, pattern):
20 self.wasRun = True
21 self.assertEqual(start_dir, expectedPath)
22 return tests
23 loader._find_tests = _find_tests
24 suite = loader.discover('test.test_unittest')
25 self.assertTrue(self.wasRun)
26 self.assertEqual(suite._tests, tests)
27
28 # Horrible white box test
29 def testNoExit(self):
30 result = object()
31 test = object()
32
33 class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
34 def run(self, test):
35 self.test = test
36 return result
37
38 runner = FakeRunner()
39
40 oldParseArgs = unittest.TestProgram.parseArgs
41 def restoreParseArgs():
42 unittest.TestProgram.parseArgs = oldParseArgs
43 unittest.TestProgram.parseArgs = lambda *args: None
44 self.addCleanup(restoreParseArgs)
45
46 def removeTest():
47 del unittest.TestProgram.test
48 unittest.TestProgram.test = test
49 self.addCleanup(removeTest)
50
51 program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
52
53 self.assertEqual(program.result, result)
54 self.assertEqual(runner.test, test)
55 self.assertEqual(program.verbosity, 2)
56
57 class ESC[4;38;5;81mFooBar(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
58 def testPass(self):
59 pass
60 def testFail(self):
61 raise AssertionError
62 def testError(self):
63 1/0
64 @unittest.skip('skipping')
65 def testSkipped(self):
66 raise AssertionError
67 @unittest.expectedFailure
68 def testExpectedFailure(self):
69 raise AssertionError
70 @unittest.expectedFailure
71 def testUnexpectedSuccess(self):
72 pass
73
74 class ESC[4;38;5;81mEmpty(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
75 pass
76
77 class ESC[4;38;5;81mTestLoader(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestLoader):
78 """Test loader that returns a suite containing the supplied testcase."""
79
80 def __init__(self, testcase):
81 self.testcase = testcase
82
83 def loadTestsFromModule(self, module):
84 return self.suiteClass(
85 [self.loadTestsFromTestCase(self.testcase)])
86
87 def loadTestsFromNames(self, names, module):
88 return self.suiteClass(
89 [self.loadTestsFromTestCase(self.testcase)])
90
91 def test_defaultTest_with_string(self):
92 class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
93 def run(self, test):
94 self.test = test
95 return True
96
97 old_argv = sys.argv
98 sys.argv = ['faketest']
99 runner = FakeRunner()
100 program = unittest.TestProgram(testRunner=runner, exit=False,
101 defaultTest='test.test_unittest',
102 testLoader=self.TestLoader(self.FooBar))
103 sys.argv = old_argv
104 self.assertEqual(('test.test_unittest',), program.testNames)
105
106 def test_defaultTest_with_iterable(self):
107 class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
108 def run(self, test):
109 self.test = test
110 return True
111
112 old_argv = sys.argv
113 sys.argv = ['faketest']
114 runner = FakeRunner()
115 program = unittest.TestProgram(
116 testRunner=runner, exit=False,
117 defaultTest=['test.test_unittest', 'test.test_unittest2'],
118 testLoader=self.TestLoader(self.FooBar))
119 sys.argv = old_argv
120 self.assertEqual(['test.test_unittest', 'test.test_unittest2'],
121 program.testNames)
122
123 def test_NonExit(self):
124 stream = BufferedWriter()
125 program = unittest.main(exit=False,
126 argv=["foobar"],
127 testRunner=unittest.TextTestRunner(stream=stream),
128 testLoader=self.TestLoader(self.FooBar))
129 self.assertTrue(hasattr(program, 'result'))
130 out = stream.getvalue()
131 self.assertIn('\nFAIL: testFail ', out)
132 self.assertIn('\nERROR: testError ', out)
133 self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
134 expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
135 'expected failures=1, unexpected successes=1)\n')
136 self.assertTrue(out.endswith(expected))
137
138 def test_Exit(self):
139 stream = BufferedWriter()
140 with self.assertRaises(SystemExit) as cm:
141 unittest.main(
142 argv=["foobar"],
143 testRunner=unittest.TextTestRunner(stream=stream),
144 exit=True,
145 testLoader=self.TestLoader(self.FooBar))
146 self.assertEqual(cm.exception.code, 1)
147 out = stream.getvalue()
148 self.assertIn('\nFAIL: testFail ', out)
149 self.assertIn('\nERROR: testError ', out)
150 self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
151 expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
152 'expected failures=1, unexpected successes=1)\n')
153 self.assertTrue(out.endswith(expected))
154
155 def test_ExitAsDefault(self):
156 stream = BufferedWriter()
157 with self.assertRaises(SystemExit):
158 unittest.main(
159 argv=["foobar"],
160 testRunner=unittest.TextTestRunner(stream=stream),
161 testLoader=self.TestLoader(self.FooBar))
162 out = stream.getvalue()
163 self.assertIn('\nFAIL: testFail ', out)
164 self.assertIn('\nERROR: testError ', out)
165 self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
166 expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
167 'expected failures=1, unexpected successes=1)\n')
168 self.assertTrue(out.endswith(expected))
169
170 def test_ExitEmptySuite(self):
171 stream = BufferedWriter()
172 with self.assertRaises(SystemExit) as cm:
173 unittest.main(
174 argv=["empty"],
175 testRunner=unittest.TextTestRunner(stream=stream),
176 testLoader=self.TestLoader(self.Empty))
177 self.assertEqual(cm.exception.code, 5)
178 out = stream.getvalue()
179 self.assertIn('\nNO TESTS RAN\n', out)
180
181
182 class ESC[4;38;5;81mInitialisableProgram(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestProgram):
183 exit = False
184 result = None
185 verbosity = 1
186 defaultTest = None
187 tb_locals = False
188 testRunner = None
189 testLoader = unittest.defaultTestLoader
190 module = '__main__'
191 progName = 'test'
192 test = 'test'
193 def __init__(self, *args):
194 pass
195
196 RESULT = object()
197
198 class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
199 initArgs = None
200 test = None
201 raiseError = 0
202
203 def __init__(self, **kwargs):
204 FakeRunner.initArgs = kwargs
205 if FakeRunner.raiseError:
206 FakeRunner.raiseError -= 1
207 raise TypeError
208
209 def run(self, test):
210 FakeRunner.test = test
211 return RESULT
212
213
214 @support.requires_subprocess()
215 class ESC[4;38;5;81mTestCommandLineArgs(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
216
217 def setUp(self):
218 self.program = InitialisableProgram()
219 self.program.createTests = lambda: None
220 FakeRunner.initArgs = None
221 FakeRunner.test = None
222 FakeRunner.raiseError = 0
223
224 def testVerbosity(self):
225 program = self.program
226
227 for opt in '-q', '--quiet':
228 program.verbosity = 1
229 program.parseArgs([None, opt])
230 self.assertEqual(program.verbosity, 0)
231
232 for opt in '-v', '--verbose':
233 program.verbosity = 1
234 program.parseArgs([None, opt])
235 self.assertEqual(program.verbosity, 2)
236
237 def testBufferCatchFailfast(self):
238 program = self.program
239 for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
240 ('catch', 'catchbreak')):
241
242 setattr(program, attr, None)
243 program.parseArgs([None])
244 self.assertIs(getattr(program, attr), False)
245
246 false = []
247 setattr(program, attr, false)
248 program.parseArgs([None])
249 self.assertIs(getattr(program, attr), false)
250
251 true = [42]
252 setattr(program, attr, true)
253 program.parseArgs([None])
254 self.assertIs(getattr(program, attr), true)
255
256 short_opt = '-%s' % arg[0]
257 long_opt = '--%s' % arg
258 for opt in short_opt, long_opt:
259 setattr(program, attr, None)
260 program.parseArgs([None, opt])
261 self.assertIs(getattr(program, attr), True)
262
263 setattr(program, attr, False)
264 with support.captured_stderr() as stderr, \
265 self.assertRaises(SystemExit) as cm:
266 program.parseArgs([None, opt])
267 self.assertEqual(cm.exception.args, (2,))
268
269 setattr(program, attr, True)
270 with support.captured_stderr() as stderr, \
271 self.assertRaises(SystemExit) as cm:
272 program.parseArgs([None, opt])
273 self.assertEqual(cm.exception.args, (2,))
274
275 def testWarning(self):
276 """Test the warnings argument"""
277 # see #10535
278 class ESC[4;38;5;81mFakeTP(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestProgram):
279 def parseArgs(self, *args, **kw): pass
280 def runTests(self, *args, **kw): pass
281 warnoptions = sys.warnoptions[:]
282 try:
283 sys.warnoptions[:] = []
284 # no warn options, no arg -> default
285 self.assertEqual(FakeTP().warnings, 'default')
286 # no warn options, w/ arg -> arg value
287 self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
288 sys.warnoptions[:] = ['somevalue']
289 # warn options, no arg -> None
290 # warn options, w/ arg -> arg value
291 self.assertEqual(FakeTP().warnings, None)
292 self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
293 finally:
294 sys.warnoptions[:] = warnoptions
295
296 def testRunTestsRunnerClass(self):
297 program = self.program
298
299 program.testRunner = FakeRunner
300 program.verbosity = 'verbosity'
301 program.failfast = 'failfast'
302 program.buffer = 'buffer'
303 program.warnings = 'warnings'
304 program.durations = '5'
305
306 program.runTests()
307
308 self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
309 'failfast': 'failfast',
310 'buffer': 'buffer',
311 'tb_locals': False,
312 'warnings': 'warnings',
313 'durations': '5'})
314 self.assertEqual(FakeRunner.test, 'test')
315 self.assertIs(program.result, RESULT)
316
317 def testRunTestsRunnerInstance(self):
318 program = self.program
319
320 program.testRunner = FakeRunner()
321 FakeRunner.initArgs = None
322
323 program.runTests()
324
325 # A new FakeRunner should not have been instantiated
326 self.assertIsNone(FakeRunner.initArgs)
327
328 self.assertEqual(FakeRunner.test, 'test')
329 self.assertIs(program.result, RESULT)
330
331 def test_locals(self):
332 program = self.program
333
334 program.testRunner = FakeRunner
335 program.parseArgs([None, '--locals'])
336 self.assertEqual(True, program.tb_locals)
337 program.runTests()
338 self.assertEqual(FakeRunner.initArgs, {'buffer': False,
339 'failfast': False,
340 'tb_locals': True,
341 'verbosity': 1,
342 'warnings': None,
343 'durations': None})
344
345 def testRunTestsOldRunnerClass(self):
346 program = self.program
347
348 # Two TypeErrors are needed to fall all the way back to old-style
349 # runners - one to fail tb_locals, one to fail buffer etc.
350 FakeRunner.raiseError = 2
351 program.testRunner = FakeRunner
352 program.verbosity = 'verbosity'
353 program.failfast = 'failfast'
354 program.buffer = 'buffer'
355 program.test = 'test'
356 program.durations = '0'
357
358 program.runTests()
359
360 # If initialising raises a type error it should be retried
361 # without the new keyword arguments
362 self.assertEqual(FakeRunner.initArgs, {})
363 self.assertEqual(FakeRunner.test, 'test')
364 self.assertIs(program.result, RESULT)
365
366 def testCatchBreakInstallsHandler(self):
367 module = sys.modules['unittest.main']
368 original = module.installHandler
369 def restore():
370 module.installHandler = original
371 self.addCleanup(restore)
372
373 self.installed = False
374 def fakeInstallHandler():
375 self.installed = True
376 module.installHandler = fakeInstallHandler
377
378 program = self.program
379 program.catchbreak = True
380 program.durations = None
381
382 program.testRunner = FakeRunner
383
384 program.runTests()
385 self.assertTrue(self.installed)
386
387 def _patch_isfile(self, names, exists=True):
388 def isfile(path):
389 return path in names
390 original = os.path.isfile
391 os.path.isfile = isfile
392 def restore():
393 os.path.isfile = original
394 self.addCleanup(restore)
395
396
397 def testParseArgsFileNames(self):
398 # running tests with filenames instead of module names
399 program = self.program
400 argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt']
401 self._patch_isfile(argv)
402
403 program.createTests = lambda: None
404 program.parseArgs(argv)
405
406 # note that 'wing.txt' is not a Python file so the name should
407 # *not* be converted to a module name
408 expected = ['foo', 'bar', 'baz', 'wing.txt']
409 self.assertEqual(program.testNames, expected)
410
411
412 def testParseArgsFilePaths(self):
413 program = self.program
414 argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
415 self._patch_isfile(argv)
416
417 program.createTests = lambda: None
418 program.parseArgs(argv)
419
420 expected = ['foo.bar.baz', 'green.red']
421 self.assertEqual(program.testNames, expected)
422
423
424 def testParseArgsNonExistentFiles(self):
425 program = self.program
426 argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
427 self._patch_isfile([])
428
429 program.createTests = lambda: None
430 program.parseArgs(argv)
431
432 self.assertEqual(program.testNames, argv[1:])
433
434 def testParseArgsAbsolutePathsThatCanBeConverted(self):
435 cur_dir = os.getcwd()
436 program = self.program
437 def _join(name):
438 return os.path.join(cur_dir, name)
439 argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')]
440 self._patch_isfile(argv)
441
442 program.createTests = lambda: None
443 program.parseArgs(argv)
444
445 expected = ['foo.bar.baz', 'green.red']
446 self.assertEqual(program.testNames, expected)
447
448 def testParseArgsAbsolutePathsThatCannotBeConverted(self):
449 program = self.program
450 # even on Windows '/...' is considered absolute by os.path.abspath
451 argv = ['progname', '/foo/bar/baz.py', '/green/red.py']
452 self._patch_isfile(argv)
453
454 program.createTests = lambda: None
455 program.parseArgs(argv)
456
457 self.assertEqual(program.testNames, argv[1:])
458
459 # it may be better to use platform specific functions to normalise paths
460 # rather than accepting '.PY' and '\' as file separator on Linux / Mac
461 # it would also be better to check that a filename is a valid module
462 # identifier (we have a regex for this in loader.py)
463 # for invalid filenames should we raise a useful error rather than
464 # leaving the current error message (import of filename fails) in place?
465
466 def testParseArgsSelectedTestNames(self):
467 program = self.program
468 argv = ['progname', '-k', 'foo', '-k', 'bar', '-k', '*pat*']
469
470 program.createTests = lambda: None
471 program.parseArgs(argv)
472
473 self.assertEqual(program.testNamePatterns, ['*foo*', '*bar*', '*pat*'])
474
475 def testSelectedTestNamesFunctionalTest(self):
476 def run_unittest(args):
477 # Use -E to ignore PYTHONSAFEPATH env var
478 cmd = [sys.executable, '-E', '-m', 'unittest'] + args
479 p = subprocess.Popen(cmd,
480 stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__))
481 with p:
482 _, stderr = p.communicate()
483 return stderr.decode()
484
485 t = '_test_warnings'
486 self.assertIn('Ran 5 tests', run_unittest([t]))
487 self.assertIn('Ran 5 tests', run_unittest(['-k', 'TestWarnings', t]))
488 self.assertIn('Ran 5 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings']))
489 self.assertIn('Ran 1 test ', run_unittest(['-k', 'f', t]))
490 self.assertIn('Ran 5 tests', run_unittest(['-k', 't', t]))
491 self.assertIn('Ran 2 tests', run_unittest(['-k', '*t', t]))
492 self.assertIn('Ran 5 tests', run_unittest(['-k', '*test_warnings.*Warning*', t]))
493 self.assertIn('Ran 1 test ', run_unittest(['-k', '*test_warnings.*warning*', t]))
494
495
496 if __name__ == '__main__':
497 unittest.main()