mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			440 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			440 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import io
 | 
						|
 | 
						|
import os
 | 
						|
import sys
 | 
						|
import subprocess
 | 
						|
from test import support
 | 
						|
import unittest
 | 
						|
import unittest.test
 | 
						|
 | 
						|
 | 
						|
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):
 | 
						|
            assert True
 | 
						|
        def testFail(self):
 | 
						|
            assert False
 | 
						|
 | 
						|
    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):
 | 
						|
        program = unittest.main(exit=False,
 | 
						|
                                argv=["foobar"],
 | 
						|
                                testRunner=unittest.TextTestRunner(stream=io.StringIO()),
 | 
						|
                                testLoader=self.FooBarLoader())
 | 
						|
        self.assertTrue(hasattr(program, 'result'))
 | 
						|
 | 
						|
 | 
						|
    def test_Exit(self):
 | 
						|
        self.assertRaises(
 | 
						|
            SystemExit,
 | 
						|
            unittest.main,
 | 
						|
            argv=["foobar"],
 | 
						|
            testRunner=unittest.TextTestRunner(stream=io.StringIO()),
 | 
						|
            exit=True,
 | 
						|
            testLoader=self.FooBarLoader())
 | 
						|
 | 
						|
 | 
						|
    def test_ExitAsDefault(self):
 | 
						|
        self.assertRaises(
 | 
						|
            SystemExit,
 | 
						|
            unittest.main,
 | 
						|
            argv=["foobar"],
 | 
						|
            testRunner=unittest.TextTestRunner(stream=io.StringIO()),
 | 
						|
            testLoader=self.FooBarLoader())
 | 
						|
 | 
						|
 | 
						|
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()
 |