123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- import io
- import os
- import sys
- import subprocess
- from test import support
- import unittest
- import unittest.test
- from unittest.test.test_result import BufferedWriter
- class Test_TestProgram(unittest.TestCase):
- def test_discovery_from_dotted_path(self):
- loader = unittest.TestLoader()
- tests = [self]
- expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
- self.wasRun = False
- def _find_tests(start_dir, pattern):
- self.wasRun = True
- self.assertEqual(start_dir, expectedPath)
- return tests
- loader._find_tests = _find_tests
- suite = loader.discover('unittest.test')
- self.assertTrue(self.wasRun)
- self.assertEqual(suite._tests, tests)
- # Horrible white box test
- def testNoExit(self):
- result = object()
- test = object()
- class FakeRunner(object):
- def run(self, test):
- self.test = test
- return result
- runner = FakeRunner()
- oldParseArgs = unittest.TestProgram.parseArgs
- def restoreParseArgs():
- unittest.TestProgram.parseArgs = oldParseArgs
- unittest.TestProgram.parseArgs = lambda *args: None
- self.addCleanup(restoreParseArgs)
- def removeTest():
- del unittest.TestProgram.test
- unittest.TestProgram.test = test
- self.addCleanup(removeTest)
- program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
- self.assertEqual(program.result, result)
- self.assertEqual(runner.test, test)
- self.assertEqual(program.verbosity, 2)
- class FooBar(unittest.TestCase):
- def testPass(self):
- pass
- def testFail(self):
- raise AssertionError
- class FooBarLoader(unittest.TestLoader):
- """Test loader that returns a suite containing FooBar."""
- def loadTestsFromModule(self, module):
- return self.suiteClass(
- [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
- def loadTestsFromNames(self, names, module):
- return self.suiteClass(
- [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
- def test_defaultTest_with_string(self):
- class FakeRunner(object):
- def run(self, test):
- self.test = test
- return True
- old_argv = sys.argv
- sys.argv = ['faketest']
- runner = FakeRunner()
- program = unittest.TestProgram(testRunner=runner, exit=False,
- defaultTest='unittest.test',
- testLoader=self.FooBarLoader())
- sys.argv = old_argv
- self.assertEqual(('unittest.test',), program.testNames)
- def test_defaultTest_with_iterable(self):
- class FakeRunner(object):
- def run(self, test):
- self.test = test
- return True
- old_argv = sys.argv
- sys.argv = ['faketest']
- runner = FakeRunner()
- program = unittest.TestProgram(
- testRunner=runner, exit=False,
- defaultTest=['unittest.test', 'unittest.test2'],
- testLoader=self.FooBarLoader())
- sys.argv = old_argv
- self.assertEqual(['unittest.test', 'unittest.test2'],
- program.testNames)
- def test_NonExit(self):
- stream = BufferedWriter()
- program = unittest.main(exit=False,
- argv=["foobar"],
- testRunner=unittest.TextTestRunner(stream=stream),
- testLoader=self.FooBarLoader())
- self.assertTrue(hasattr(program, 'result'))
- self.assertIn('\nFAIL: testFail ', stream.getvalue())
- self.assertTrue(stream.getvalue().endswith('\n\nFAILED (failures=1)\n'))
- def test_Exit(self):
- stream = BufferedWriter()
- self.assertRaises(
- SystemExit,
- unittest.main,
- argv=["foobar"],
- testRunner=unittest.TextTestRunner(stream=stream),
- exit=True,
- testLoader=self.FooBarLoader())
- self.assertIn('\nFAIL: testFail ', stream.getvalue())
- self.assertTrue(stream.getvalue().endswith('\n\nFAILED (failures=1)\n'))
- def test_ExitAsDefault(self):
- stream = BufferedWriter()
- self.assertRaises(
- SystemExit,
- unittest.main,
- argv=["foobar"],
- testRunner=unittest.TextTestRunner(stream=stream),
- testLoader=self.FooBarLoader())
- self.assertIn('\nFAIL: testFail ', stream.getvalue())
- self.assertTrue(stream.getvalue().endswith('\n\nFAILED (failures=1)\n'))
- class InitialisableProgram(unittest.TestProgram):
- exit = False
- result = None
- verbosity = 1
- defaultTest = None
- tb_locals = False
- testRunner = None
- testLoader = unittest.defaultTestLoader
- module = '__main__'
- progName = 'test'
- test = 'test'
- def __init__(self, *args):
- pass
- RESULT = object()
- class FakeRunner(object):
- initArgs = None
- test = None
- raiseError = 0
- def __init__(self, **kwargs):
- FakeRunner.initArgs = kwargs
- if FakeRunner.raiseError:
- FakeRunner.raiseError -= 1
- raise TypeError
- def run(self, test):
- FakeRunner.test = test
- return RESULT
- class TestCommandLineArgs(unittest.TestCase):
- def setUp(self):
- self.program = InitialisableProgram()
- self.program.createTests = lambda: None
- FakeRunner.initArgs = None
- FakeRunner.test = None
- FakeRunner.raiseError = 0
- def testVerbosity(self):
- program = self.program
- for opt in '-q', '--quiet':
- program.verbosity = 1
- program.parseArgs([None, opt])
- self.assertEqual(program.verbosity, 0)
- for opt in '-v', '--verbose':
- program.verbosity = 1
- program.parseArgs([None, opt])
- self.assertEqual(program.verbosity, 2)
- def testBufferCatchFailfast(self):
- program = self.program
- for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
- ('catch', 'catchbreak')):
- setattr(program, attr, None)
- program.parseArgs([None])
- self.assertIs(getattr(program, attr), False)
- false = []
- setattr(program, attr, false)
- program.parseArgs([None])
- self.assertIs(getattr(program, attr), false)
- true = [42]
- setattr(program, attr, true)
- program.parseArgs([None])
- self.assertIs(getattr(program, attr), true)
- short_opt = '-%s' % arg[0]
- long_opt = '--%s' % arg
- for opt in short_opt, long_opt:
- setattr(program, attr, None)
- program.parseArgs([None, opt])
- self.assertIs(getattr(program, attr), True)
- setattr(program, attr, False)
- with support.captured_stderr() as stderr, \
- self.assertRaises(SystemExit) as cm:
- program.parseArgs([None, opt])
- self.assertEqual(cm.exception.args, (2,))
- setattr(program, attr, True)
- with support.captured_stderr() as stderr, \
- self.assertRaises(SystemExit) as cm:
- program.parseArgs([None, opt])
- self.assertEqual(cm.exception.args, (2,))
- def testWarning(self):
- """Test the warnings argument"""
- # see #10535
- class FakeTP(unittest.TestProgram):
- def parseArgs(self, *args, **kw): pass
- def runTests(self, *args, **kw): pass
- warnoptions = sys.warnoptions[:]
- try:
- sys.warnoptions[:] = []
- # no warn options, no arg -> default
- self.assertEqual(FakeTP().warnings, 'default')
- # no warn options, w/ arg -> arg value
- self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
- sys.warnoptions[:] = ['somevalue']
- # warn options, no arg -> None
- # warn options, w/ arg -> arg value
- self.assertEqual(FakeTP().warnings, None)
- self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
- finally:
- sys.warnoptions[:] = warnoptions
- def testRunTestsRunnerClass(self):
- program = self.program
- program.testRunner = FakeRunner
- program.verbosity = 'verbosity'
- program.failfast = 'failfast'
- program.buffer = 'buffer'
- program.warnings = 'warnings'
- program.runTests()
- self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
- 'failfast': 'failfast',
- 'buffer': 'buffer',
- 'tb_locals': False,
- 'warnings': 'warnings'})
- self.assertEqual(FakeRunner.test, 'test')
- self.assertIs(program.result, RESULT)
- def testRunTestsRunnerInstance(self):
- program = self.program
- program.testRunner = FakeRunner()
- FakeRunner.initArgs = None
- program.runTests()
- # A new FakeRunner should not have been instantiated
- self.assertIsNone(FakeRunner.initArgs)
- self.assertEqual(FakeRunner.test, 'test')
- self.assertIs(program.result, RESULT)
- def test_locals(self):
- program = self.program
- program.testRunner = FakeRunner
- program.parseArgs([None, '--locals'])
- self.assertEqual(True, program.tb_locals)
- program.runTests()
- self.assertEqual(FakeRunner.initArgs, {'buffer': False,
- 'failfast': False,
- 'tb_locals': True,
- 'verbosity': 1,
- 'warnings': None})
- def testRunTestsOldRunnerClass(self):
- program = self.program
- # Two TypeErrors are needed to fall all the way back to old-style
- # runners - one to fail tb_locals, one to fail buffer etc.
- FakeRunner.raiseError = 2
- program.testRunner = FakeRunner
- program.verbosity = 'verbosity'
- program.failfast = 'failfast'
- program.buffer = 'buffer'
- program.test = 'test'
- program.runTests()
- # If initialising raises a type error it should be retried
- # without the new keyword arguments
- self.assertEqual(FakeRunner.initArgs, {})
- self.assertEqual(FakeRunner.test, 'test')
- self.assertIs(program.result, RESULT)
- def testCatchBreakInstallsHandler(self):
- module = sys.modules['unittest.main']
- original = module.installHandler
- def restore():
- module.installHandler = original
- self.addCleanup(restore)
- self.installed = False
- def fakeInstallHandler():
- self.installed = True
- module.installHandler = fakeInstallHandler
- program = self.program
- program.catchbreak = True
- program.testRunner = FakeRunner
- program.runTests()
- self.assertTrue(self.installed)
- def _patch_isfile(self, names, exists=True):
- def isfile(path):
- return path in names
- original = os.path.isfile
- os.path.isfile = isfile
- def restore():
- os.path.isfile = original
- self.addCleanup(restore)
- def testParseArgsFileNames(self):
- # running tests with filenames instead of module names
- program = self.program
- argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt']
- self._patch_isfile(argv)
- program.createTests = lambda: None
- program.parseArgs(argv)
- # note that 'wing.txt' is not a Python file so the name should
- # *not* be converted to a module name
- expected = ['foo', 'bar', 'baz', 'wing.txt']
- self.assertEqual(program.testNames, expected)
- def testParseArgsFilePaths(self):
- program = self.program
- argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
- self._patch_isfile(argv)
- program.createTests = lambda: None
- program.parseArgs(argv)
- expected = ['foo.bar.baz', 'green.red']
- self.assertEqual(program.testNames, expected)
- def testParseArgsNonExistentFiles(self):
- program = self.program
- argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
- self._patch_isfile([])
- program.createTests = lambda: None
- program.parseArgs(argv)
- self.assertEqual(program.testNames, argv[1:])
- def testParseArgsAbsolutePathsThatCanBeConverted(self):
- cur_dir = os.getcwd()
- program = self.program
- def _join(name):
- return os.path.join(cur_dir, name)
- argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')]
- self._patch_isfile(argv)
- program.createTests = lambda: None
- program.parseArgs(argv)
- expected = ['foo.bar.baz', 'green.red']
- self.assertEqual(program.testNames, expected)
- def testParseArgsAbsolutePathsThatCannotBeConverted(self):
- program = self.program
- # even on Windows '/...' is considered absolute by os.path.abspath
- argv = ['progname', '/foo/bar/baz.py', '/green/red.py']
- self._patch_isfile(argv)
- program.createTests = lambda: None
- program.parseArgs(argv)
- self.assertEqual(program.testNames, argv[1:])
- # it may be better to use platform specific functions to normalise paths
- # rather than accepting '.PY' and '\' as file separator on Linux / Mac
- # it would also be better to check that a filename is a valid module
- # identifier (we have a regex for this in loader.py)
- # for invalid filenames should we raise a useful error rather than
- # leaving the current error message (import of filename fails) in place?
- def testParseArgsSelectedTestNames(self):
- program = self.program
- argv = ['progname', '-k', 'foo', '-k', 'bar', '-k', '*pat*']
- program.createTests = lambda: None
- program.parseArgs(argv)
- self.assertEqual(program.testNamePatterns, ['*foo*', '*bar*', '*pat*'])
- def testSelectedTestNamesFunctionalTest(self):
- def run_unittest(args):
- p = subprocess.Popen([sys.executable, '-m', 'unittest'] + args,
- stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__))
- with p:
- _, stderr = p.communicate()
- return stderr.decode()
- t = '_test_warnings'
- self.assertIn('Ran 7 tests', run_unittest([t]))
- self.assertIn('Ran 7 tests', run_unittest(['-k', 'TestWarnings', t]))
- self.assertIn('Ran 7 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings']))
- self.assertIn('Ran 2 tests', run_unittest(['-k', 'f', t]))
- self.assertIn('Ran 7 tests', run_unittest(['-k', 't', t]))
- self.assertIn('Ran 3 tests', run_unittest(['-k', '*t', t]))
- self.assertIn('Ran 7 tests', run_unittest(['-k', '*test_warnings.*Warning*', t]))
- self.assertIn('Ran 1 test', run_unittest(['-k', '*test_warnings.*warning*', t]))
- if __name__ == '__main__':
- unittest.main()
|