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