diff options
Diffstat (limited to 'Lib/unittest/test/test_program.py')
| -rw-r--r-- | Lib/unittest/test/test_program.py | 358 | 
1 files changed, 358 insertions, 0 deletions
| diff --git a/Lib/unittest/test/test_program.py b/Lib/unittest/test/test_program.py new file mode 100644 index 0000000..d5d0f5a --- /dev/null +++ b/Lib/unittest/test/test_program.py @@ -0,0 +1,358 @@ +import io + +import os +import sys +import unittest + + +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 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 +    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 = False + +    def __init__(self, **kwargs): +        FakeRunner.initArgs = kwargs +        if FakeRunner.raiseError: +            FakeRunner.raiseError = False +            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 = False + +    def testHelpAndUnknown(self): +        program = self.program +        def usageExit(msg=None): +            program.msg = msg +            program.exit = True +        program.usageExit = usageExit + +        for opt in '-h', '-H', '--help': +            program.exit = False +            program.parseArgs([None, opt]) +            self.assertTrue(program.exit) +            self.assertIsNone(program.msg) + +        program.parseArgs([None, '-$']) +        self.assertTrue(program.exit) +        self.assertIsNotNone(program.msg) + +    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')): +            if attr == 'catch' and not hasInstallHandler: +                continue + +            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.assertTrue(getattr(program, attr)) + +            for opt in short_opt, long_opt: +                not_none = object() +                setattr(program, attr, not_none) + +                program.parseArgs([None, opt]) +                self.assertEqual(getattr(program, attr), not_none) + +    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', +                                                '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 testRunTestsOldRunnerClass(self): +        program = self.program + +        FakeRunner.raiseError = True +        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 seprator 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? + + +if __name__ == '__main__': +    unittest.main() | 
