blob: 97d7a24b5d3af70890f3a09285e50295e047a8e1 [file] [log] [blame]
Michael Foord2560e5c2010-03-27 12:34:21 +00001import io
2
Michael Foord4a8cf3c2010-05-07 15:35:24 +00003import os
Michael Foord56fdb752010-05-07 16:00:30 +00004import sys
Michael Foord2560e5c2010-03-27 12:34:21 +00005import unittest
6
7
8class Test_TestProgram(unittest.TestCase):
9
Michael Foord4a8cf3c2010-05-07 15:35:24 +000010 def test_discovery_from_dotted_path(self):
11 loader = unittest.TestLoader()
12
13 tests = [self]
14 expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
15
16 self.wasRun = False
17 def _find_tests(start_dir, pattern):
18 self.wasRun = True
19 self.assertEqual(start_dir, expectedPath)
20 return tests
21 loader._find_tests = _find_tests
22 suite = loader.discover('unittest.test')
23 self.assertTrue(self.wasRun)
24 self.assertEqual(suite._tests, tests)
25
Michael Foord2560e5c2010-03-27 12:34:21 +000026 # Horrible white box test
27 def testNoExit(self):
28 result = object()
29 test = object()
30
31 class FakeRunner(object):
32 def run(self, test):
33 self.test = test
34 return result
35
36 runner = FakeRunner()
37
38 oldParseArgs = unittest.TestProgram.parseArgs
39 def restoreParseArgs():
40 unittest.TestProgram.parseArgs = oldParseArgs
41 unittest.TestProgram.parseArgs = lambda *args: None
42 self.addCleanup(restoreParseArgs)
43
44 def removeTest():
45 del unittest.TestProgram.test
46 unittest.TestProgram.test = test
47 self.addCleanup(removeTest)
48
49 program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
50
51 self.assertEqual(program.result, result)
52 self.assertEqual(runner.test, test)
53 self.assertEqual(program.verbosity, 2)
54
55 class FooBar(unittest.TestCase):
56 def testPass(self):
57 assert True
58 def testFail(self):
59 assert False
60
61 class FooBarLoader(unittest.TestLoader):
62 """Test loader that returns a suite containing FooBar."""
63 def loadTestsFromModule(self, module):
64 return self.suiteClass(
65 [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
66
Petri Lehtinen20054472013-02-23 18:52:51 +010067 def loadTestsFromNames(self, names, module):
68 return self.suiteClass(
69 [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
70
71 def test_defaultTest_with_string(self):
72 class FakeRunner(object):
73 def run(self, test):
74 self.test = test
75 return True
76
77 old_argv = sys.argv
78 sys.argv = ['faketest']
79 runner = FakeRunner()
80 program = unittest.TestProgram(testRunner=runner, exit=False,
81 defaultTest='unittest.test',
82 testLoader=self.FooBarLoader())
83 sys.argv = old_argv
Ezio Melotticf936c72013-03-23 16:46:23 +020084 self.assertEqual(('unittest.test',), program.testNames)
Petri Lehtinen20054472013-02-23 18:52:51 +010085
86 def test_defaultTest_with_iterable(self):
87 class FakeRunner(object):
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(
96 testRunner=runner, exit=False,
97 defaultTest=['unittest.test', 'unittest.test2'],
98 testLoader=self.FooBarLoader())
99 sys.argv = old_argv
Ezio Melotticf936c72013-03-23 16:46:23 +0200100 self.assertEqual(['unittest.test', 'unittest.test2'],
Petri Lehtinen20054472013-02-23 18:52:51 +0100101 program.testNames)
Michael Foord2560e5c2010-03-27 12:34:21 +0000102
103 def test_NonExit(self):
104 program = unittest.main(exit=False,
105 argv=["foobar"],
106 testRunner=unittest.TextTestRunner(stream=io.StringIO()),
107 testLoader=self.FooBarLoader())
108 self.assertTrue(hasattr(program, 'result'))
109
110
111 def test_Exit(self):
112 self.assertRaises(
113 SystemExit,
114 unittest.main,
115 argv=["foobar"],
116 testRunner=unittest.TextTestRunner(stream=io.StringIO()),
117 exit=True,
118 testLoader=self.FooBarLoader())
119
120
121 def test_ExitAsDefault(self):
122 self.assertRaises(
123 SystemExit,
124 unittest.main,
125 argv=["foobar"],
126 testRunner=unittest.TextTestRunner(stream=io.StringIO()),
127 testLoader=self.FooBarLoader())
Michael Foord56fdb752010-05-07 16:00:30 +0000128
129
130class InitialisableProgram(unittest.TestProgram):
131 exit = False
132 result = None
133 verbosity = 1
134 defaultTest = None
135 testRunner = None
136 testLoader = unittest.defaultTestLoader
Michael Foordf100dbd2010-12-19 03:59:10 +0000137 module = '__main__'
Michael Foord56fdb752010-05-07 16:00:30 +0000138 progName = 'test'
139 test = 'test'
140 def __init__(self, *args):
141 pass
142
143RESULT = object()
144
145class FakeRunner(object):
146 initArgs = None
147 test = None
148 raiseError = False
149
150 def __init__(self, **kwargs):
151 FakeRunner.initArgs = kwargs
152 if FakeRunner.raiseError:
153 FakeRunner.raiseError = False
154 raise TypeError
155
156 def run(self, test):
157 FakeRunner.test = test
158 return RESULT
159
160class TestCommandLineArgs(unittest.TestCase):
161
162 def setUp(self):
163 self.program = InitialisableProgram()
164 self.program.createTests = lambda: None
165 FakeRunner.initArgs = None
166 FakeRunner.test = None
167 FakeRunner.raiseError = False
168
Michael Foord56fdb752010-05-07 16:00:30 +0000169 def testVerbosity(self):
170 program = self.program
171
172 for opt in '-q', '--quiet':
173 program.verbosity = 1
174 program.parseArgs([None, opt])
175 self.assertEqual(program.verbosity, 0)
176
177 for opt in '-v', '--verbose':
178 program.verbosity = 1
179 program.parseArgs([None, opt])
180 self.assertEqual(program.verbosity, 2)
181
182 def testBufferCatchFailfast(self):
183 program = self.program
184 for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
185 ('catch', 'catchbreak')):
186 if attr == 'catch' and not hasInstallHandler:
187 continue
188
189 short_opt = '-%s' % arg[0]
190 long_opt = '--%s' % arg
191 for opt in short_opt, long_opt:
192 setattr(program, attr, None)
193
194 program.parseArgs([None, opt])
195 self.assertTrue(getattr(program, attr))
196
197 for opt in short_opt, long_opt:
198 not_none = object()
199 setattr(program, attr, not_none)
200
201 program.parseArgs([None, opt])
202 self.assertEqual(getattr(program, attr), not_none)
203
Ezio Melotti60901872010-12-01 00:56:10 +0000204 def testWarning(self):
205 """Test the warnings argument"""
206 # see #10535
207 class FakeTP(unittest.TestProgram):
208 def parseArgs(self, *args, **kw): pass
209 def runTests(self, *args, **kw): pass
Ezio Melotti60c3c9f2011-03-20 15:31:26 +0200210 warnoptions = sys.warnoptions[:]
Ezio Melotti60901872010-12-01 00:56:10 +0000211 try:
212 sys.warnoptions[:] = []
213 # no warn options, no arg -> default
214 self.assertEqual(FakeTP().warnings, 'default')
215 # no warn options, w/ arg -> arg value
216 self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
217 sys.warnoptions[:] = ['somevalue']
218 # warn options, no arg -> None
219 # warn options, w/ arg -> arg value
220 self.assertEqual(FakeTP().warnings, None)
221 self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
222 finally:
223 sys.warnoptions[:] = warnoptions
224
Michael Foord56fdb752010-05-07 16:00:30 +0000225 def testRunTestsRunnerClass(self):
226 program = self.program
227
228 program.testRunner = FakeRunner
229 program.verbosity = 'verbosity'
230 program.failfast = 'failfast'
231 program.buffer = 'buffer'
Ezio Melotti60901872010-12-01 00:56:10 +0000232 program.warnings = 'warnings'
Michael Foord56fdb752010-05-07 16:00:30 +0000233
234 program.runTests()
235
236 self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
237 'failfast': 'failfast',
Ezio Melotti60901872010-12-01 00:56:10 +0000238 'buffer': 'buffer',
239 'warnings': 'warnings'})
Michael Foord56fdb752010-05-07 16:00:30 +0000240 self.assertEqual(FakeRunner.test, 'test')
241 self.assertIs(program.result, RESULT)
242
243 def testRunTestsRunnerInstance(self):
244 program = self.program
245
246 program.testRunner = FakeRunner()
247 FakeRunner.initArgs = None
248
249 program.runTests()
250
251 # A new FakeRunner should not have been instantiated
252 self.assertIsNone(FakeRunner.initArgs)
253
254 self.assertEqual(FakeRunner.test, 'test')
255 self.assertIs(program.result, RESULT)
256
257 def testRunTestsOldRunnerClass(self):
258 program = self.program
259
260 FakeRunner.raiseError = True
261 program.testRunner = FakeRunner
262 program.verbosity = 'verbosity'
263 program.failfast = 'failfast'
264 program.buffer = 'buffer'
265 program.test = 'test'
266
267 program.runTests()
268
269 # If initialising raises a type error it should be retried
270 # without the new keyword arguments
271 self.assertEqual(FakeRunner.initArgs, {})
272 self.assertEqual(FakeRunner.test, 'test')
273 self.assertIs(program.result, RESULT)
274
275 def testCatchBreakInstallsHandler(self):
276 module = sys.modules['unittest.main']
277 original = module.installHandler
278 def restore():
279 module.installHandler = original
280 self.addCleanup(restore)
281
282 self.installed = False
283 def fakeInstallHandler():
284 self.installed = True
285 module.installHandler = fakeInstallHandler
286
287 program = self.program
288 program.catchbreak = True
289
290 program.testRunner = FakeRunner
291
292 program.runTests()
293 self.assertTrue(self.installed)
294
Michael Foord37d120a2010-12-04 01:11:21 +0000295 def _patch_isfile(self, names, exists=True):
296 def isfile(path):
297 return path in names
298 original = os.path.isfile
299 os.path.isfile = isfile
300 def restore():
301 os.path.isfile = original
302 self.addCleanup(restore)
303
304
305 def testParseArgsFileNames(self):
306 # running tests with filenames instead of module names
307 program = self.program
308 argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt']
309 self._patch_isfile(argv)
310
311 program.createTests = lambda: None
312 program.parseArgs(argv)
313
314 # note that 'wing.txt' is not a Python file so the name should
315 # *not* be converted to a module name
316 expected = ['foo', 'bar', 'baz', 'wing.txt']
317 self.assertEqual(program.testNames, expected)
318
319
320 def testParseArgsFilePaths(self):
321 program = self.program
322 argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
323 self._patch_isfile(argv)
324
325 program.createTests = lambda: None
326 program.parseArgs(argv)
327
328 expected = ['foo.bar.baz', 'green.red']
329 self.assertEqual(program.testNames, expected)
330
331
332 def testParseArgsNonExistentFiles(self):
333 program = self.program
334 argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
335 self._patch_isfile([])
336
337 program.createTests = lambda: None
338 program.parseArgs(argv)
339
340 self.assertEqual(program.testNames, argv[1:])
341
342 def testParseArgsAbsolutePathsThatCanBeConverted(self):
343 cur_dir = os.getcwd()
344 program = self.program
345 def _join(name):
346 return os.path.join(cur_dir, name)
347 argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')]
348 self._patch_isfile(argv)
349
350 program.createTests = lambda: None
351 program.parseArgs(argv)
352
353 expected = ['foo.bar.baz', 'green.red']
354 self.assertEqual(program.testNames, expected)
355
356 def testParseArgsAbsolutePathsThatCannotBeConverted(self):
357 program = self.program
Michael Foord36526bf2010-12-04 01:43:59 +0000358 # even on Windows '/...' is considered absolute by os.path.abspath
Michael Foord37d120a2010-12-04 01:11:21 +0000359 argv = ['progname', '/foo/bar/baz.py', '/green/red.py']
360 self._patch_isfile(argv)
361
362 program.createTests = lambda: None
363 program.parseArgs(argv)
364
365 self.assertEqual(program.testNames, argv[1:])
366
367 # it may be better to use platform specific functions to normalise paths
368 # rather than accepting '.PY' and '\' as file seprator on Linux / Mac
369 # it would also be better to check that a filename is a valid module
370 # identifier (we have a regex for this in loader.py)
371 # for invalid filenames should we raise a useful error rather than
372 # leaving the current error message (import of filename fails) in place?
373
Michael Foord56fdb752010-05-07 16:00:30 +0000374
375if __name__ == '__main__':
376 unittest.main()