Exemple #1
0
 def test_shouldStop(self):
     """
     When result.shouldStop == True, the suite should exit early.
     """
     mock_test = MagicMock()
     gts = GreenTestSuite(args=default_args)
     gts._tests = (mock_test,)
     mock_result = MagicMock()
     mock_result.shouldStop = True
     gts.run(mock_result)
Exemple #2
0
 def test_failedModuleSetup(self):
     """
     When module setup fails, we skip to the next test.
     """
     mock_test = MagicMock()
     mock_test.__iter__.side_effect = TypeError
     gts = GreenTestSuite(args=default_args)
     gts._tests = (mock_test,)
     mock_result = MagicMock()
     mock_result._moduleSetUpFailed = True
     mock_result.shouldStop = False
     gts.run(mock_result)
Exemple #3
0
 def test_addTest_testPattern(self):
     """
     Setting test_pattern will cause a test to be filtered.
     """
     mock_test = MagicMock()
     mock_test._testMethodName = 'test_hello'
     mock_test2 = MagicMock()
     mock_test2._testMethodName = 'test_goodbye'
     args = copy.deepcopy(default_args)
     args.test_pattern = '_good*'
     gts = GreenTestSuite(args=args)
     gts.addTest(mock_test)
     self.assertEqual(gts._tests, [])
     gts.addTest(mock_test2)
     self.assertEqual(gts._tests, [mock_test2])
Exemple #4
0
 def test_GreenStream(self):
     """
     run() can use a GreenStream for output.
     """
     gs = GreenStream(self.stream)
     run(GreenTestSuite(), gs, args=self.args)
     self.assertIn("No Tests Found", self.stream.getvalue())
Exemple #5
0
def loadTargets(targets, file_pattern='test*.py'):
    # If a string was passed in, put it into a list.
    if type(targets) != list:
        targets = [targets]

    # Make sure there are no duplicate entries, preserving order
    target_dict = OrderedDict()
    for target in targets:
        target_dict[target] = True
    targets = target_dict.keys()

    suites = []
    for target in targets:
        suite = loadTarget(target, file_pattern)
        if not suite:
            debug("Found 0 tests for target '{}'".format(target))
            continue
        suites.append(suite)
        num_tests = suite.countTestCases()
        debug("Found {} test{} for target '{}'".format(
            num_tests, '' if (num_tests == 1) else 's', target))

    if suites:
        return GreenTestSuite(suites)
    else:
        return None
Exemple #6
0
def loadFromModuleFilename(filename):
    dotted_module, parent_dir = findDottedModuleAndParentDir(filename)
    # Adding the parent path of the module to the start of sys.path is
    # the closest we can get to an absolute import in Python that I can
    # find.
    sys.path.insert(0, parent_dir)
    try:
        __import__(dotted_module)
        loaded_module = sys.modules[dotted_module]
        debug("Imported {}".format(dotted_module), 2)
    except unittest.case.SkipTest as e:
        # TODO: #25 - Right now this mimics the behavior in unittest.  Lets
        # refactor it and simplify it after we make sure it works.
        # This is a cause of the traceback mangling I observed.
        reason = str(e)

        @unittest.case.skip(reason)
        def testSkipped(self):
            pass  # pragma: no cover

        TestClass = type(
                str("ModuleSkipped"),
                (unittest.case.TestCase,),
                {filename: testSkipped})
        return GreenTestSuite((TestClass(filename),))
    except:
        # TODO: #25 - Right now this mimics the behavior in unittest.  Lets
        # refactor it and simplify it after we make sure it works.
        # This is a cause of the traceback mangling I observed.
        message = ('Failed to import {} computed from filename {}\n{}').format(
                       dotted_module, filename, traceback.format_exc())

        def testFailure(self):
            raise ImportError(message)

        TestClass = type(
                str("ModuleImportFailure"),
                (unittest.case.TestCase,),
                {filename: testFailure})
        return GreenTestSuite((TestClass(filename),))
    finally:
        # This gets called before return statements in except clauses
        # actually return.  Yay!
        sys.path.pop(0)

    # --- Find the tests inside the loaded module ---
    return loadFromModule(loaded_module)
Exemple #7
0
 def test_empty(self):
     """
     run() does not crash with empty suite and processes
     """
     suite = GreenTestSuite()
     self.args.processes = 2
     self.args.termcolor = False
     run(suite, self.stream, self.args)
Exemple #8
0
 def test_noTestsFound(self):
     """
     When we don't find any tests, we say so.
     """
     result = run(GreenTestSuite(), self.stream, self.args)
     self.assertIn('No Tests Found', self.stream.getvalue())
     self.assertEqual(result.testsRun, 0)
     self.assertEqual(result.wasSuccessful(), False)
Exemple #9
0
 def test_failedModuleTeardown(self):
     """
     When module teardown fails, we report an error.
     """
     mock_module = MagicMock()
     mock_test = MagicMock()
     mock_err = MagicMock()
     args = copy.deepcopy(default_args)
     gts = GreenTestSuite(args=args)
     gts._get_previous_module = mock_module
     mock_result = MagicMock()
     mock_result.errors.__len__.side_effect = [0, 1, 1]
     mock_result.errors.__getitem__.side_effect = [[],
                                                   [(mock_test, mock_err)]]
     mock_result._previousTestClass.__name__ = "mockClass"
     gts.run(mock_result)
     self.assertTrue(mock_test.is_class_or_module_teardown_error)
Exemple #10
0
 def test_stdout(self):
     """
     run() can use sys.stdout as the stream.
     """
     saved_stdout = sys.stdout
     sys.stdout = self.stream
     self.addCleanup(setattr, sys, 'stdout', saved_stdout)
     run(GreenTestSuite(), sys.stdout, args=self.args)
     self.assertIn('No Tests Found', self.stream.getvalue())
Exemple #11
0
    def test_skip_in_setUpClass(self):
        """
        If SkipTest is raised in setUpClass, then the test gets skipped
        """
        gts =  GreenTestSuite(args=default_args)
        mock_test = MagicMock()
        mock_result = MagicMock()
        mock_class = MagicMock()
        mock_result._previousTestClass = None
        mock_result._moduleSetUpFailed = None
        mock_result.__unittest_skip__ = None
        mock_test.__class__ = mock_class
        mock_class.setUpClass.side_effect = unittest.SkipTest("kaboom")

        gts._handleClassSetUp(mock_test, mock_result)

        self.assertTrue(mock_class.__unittest_skip__)
        self.assertEqual(mock_class.__unittest_skip_why__, "kaboom")
Exemple #12
0
    def test_skip_in_setUpClass(self):
        """
        If SkipTest is raised in setUpClass, then the test gets skipped
        """
        gts =  GreenTestSuite(args=default_args)
        mock_test = MagicMock()
        mock_result = MagicMock()
        mock_class = MagicMock()
        mock_result._previousTestClass = None
        mock_result._moduleSetUpFailed = None
        mock_result.__unittest_skip__ = None
        mock_test.__class__ = mock_class
        mock_class.setUpClass.side_effect = unittest.SkipTest("kaboom")

        gts._handleClassSetUp(mock_test, mock_result)

        self.assertTrue(mock_class.__unittest_skip__)
        self.assertEqual(mock_class.__unittest_skip_why__, "kaboom")
Exemple #13
0
 def test_allow_stdout(self):
     """
     The allow_stdout setting should not get ignored.
     """
     class Object(object):
         pass
     args = Object()
     args.allow_stdout = True
     gts = GreenTestSuite(args=args)
     self.assertEqual(gts.allow_stdout, True)
Exemple #14
0
    def discover(self,
                 current_path,
                 file_pattern="test*.py",
                 top_level_dir=None):
        """
        I take a path to a directory and discover all the tests inside files
        matching file_pattern.

        If path is not a readable directory, I raise an ImportError.

        If I don't find anything, I return None.  Otherwise I return a
        GreenTestSuite
        """
        current_abspath = os.path.abspath(current_path)
        if not os.path.isdir(current_abspath):
            raise ImportError("'{}' is not a directory".format(
                str(current_path)))
        suite = GreenTestSuite()
        try:
            for file_or_dir_name in sorted(os.listdir(current_abspath)):
                path = os.path.join(current_abspath, file_or_dir_name)
                # Recurse into directories, attempting to skip virtual environments
                bin_activate = os.path.join(path, "bin", "activate")
                if os.path.isdir(path) and not os.path.isfile(bin_activate):
                    # Don't follow symlinks
                    if os.path.islink(path):
                        continue
                    # Don't recurse into directories that couldn't be a package name
                    if not python_dir_pattern.match(file_or_dir_name):
                        continue

                    subdir_suite = self.discover(
                        path,
                        file_pattern=file_pattern,
                        top_level_dir=top_level_dir or current_path,
                    )

                    if subdir_suite:
                        suite.addTest(subdir_suite)

                elif os.path.isfile(path):
                    # Skip irrelevant files
                    if not python_file_pattern.match(file_or_dir_name):
                        continue
                    if not fnmatch(file_or_dir_name, file_pattern):
                        continue

                    # Try loading the file as a module
                    module_suite = self.loadFromModuleFilename(path)
                    if module_suite:
                        suite.addTest(module_suite)
        except OSError:
            debug("WARNING: Test discovery failed at path {}".format(
                current_path))

        return flattenTestSuite(suite) if suite.countTestCases() else None
Exemple #15
0
def loadFromTestCase(test_case_class):
    debug("Examining test case {}".format(test_case_class.__name__), 3)
    test_case_names = list(
        filter(
            lambda attrname: (attrname.startswith('test') and callable(
                getattr(test_case_class, attrname)) and not isTestCaseDisabled(
                    test_case_class, attrname)), dir(test_case_class)))
    debug("Test case names: {}".format(test_case_names))
    test_case_names.sort(
        key=functools.cmp_to_key(lambda x, y: (x > y) - (x < y)))
    if not test_case_names and hasattr(test_case_class, 'runTest'):
        test_case_names = ['runTest']
    return GreenTestSuite(map(test_case_class, test_case_names))
Exemple #16
0
    def discover(self, current_path, file_pattern='test*.py',
                 top_level_dir=None):
        """
        I take a path to a directory and discover all the tests inside files
        matching file_pattern.

        If path is not a readable directory, I raise an ImportError.

        If I don't find anything, I return None.  Otherwise I return a
        GreenTestSuite
        """
        current_abspath = os.path.abspath(current_path)
        if not os.path.isdir(current_abspath):
            raise ImportError(
                    "'{}' is not a directory".format(str(current_path)))
        suite = GreenTestSuite()
        try:
            for file_or_dir_name in sorted(os.listdir(current_abspath)):
                path = os.path.join(current_abspath, file_or_dir_name)
                # Recurse into directories, attempting to skip virtual environments
                bin_activate = os.path.join(path, 'bin', 'activate')
                if os.path.isdir(path) and not os.path.isfile(bin_activate):
                    # Don't follow symlinks
                    if os.path.islink(path):
                        continue
                    # Don't recurse into directories that couldn't be a package name
                    if not python_dir_pattern.match(file_or_dir_name):
                        continue

                    subdir_suite = self.discover(
                        path, file_pattern=file_pattern,
                        top_level_dir=top_level_dir or current_path
                    )

                    if subdir_suite:
                        suite.addTest(subdir_suite)

                elif os.path.isfile(path):
                    # Skip irrelevant files
                    if not python_file_pattern.match(file_or_dir_name):
                        continue
                    if not fnmatch(file_or_dir_name, file_pattern):
                        continue

                    # Try loading the file as a module
                    module_suite = self.loadFromModuleFilename(path)
                    if module_suite:
                        suite.addTest(module_suite)
        except OSError:
            debug("WARNING: Test discovery failed at path {}".format(current_path))

        return flattenTestSuite(suite) if suite.countTestCases() else None
Exemple #17
0
 def test_addTest_testPattern(self):
     """
     Setting test_pattern will cause a test to be filtered.
     """
     mock_test = MagicMock()
     mock_test._testMethodName = "test_hello"
     mock_test2 = MagicMock()
     mock_test2._testMethodName = "test_goodbye"
     args = copy.deepcopy(default_args)
     args.test_pattern = "_good*"
     gts = GreenTestSuite(args=args)
     gts.addTest(mock_test)
     self.assertEqual(gts._tests, [])
     gts.addTest(mock_test2)
     self.assertEqual(gts._tests, [mock_test2])
Exemple #18
0
    def run_tests(self):
        import sys
        if sys.version_info[:2] == (2, 6):
            import unittest2 as unittest  # Python 2.6
        else:
            import unittest

        setup_file = sys.modules['__main__'].__file__
        setup_dir = os.path.abspath(os.path.dirname(setup_file))
        tests = unittest.TestLoader().discover(os.path.join(
            setup_dir, 'tests'),
                                               pattern='*.py')
        try:
            # https://github.com/CleanCut/green/issues/50
            from green.runner import run
            from green.suite import GreenTestSuite
            from green.config import default_args
            default_args.verbose = 3
            run(GreenTestSuite(tests), sys.stdout, default_args)
        except ImportError:
            unittest.TextTestRunner(verbosity=2).run(tests)
Exemple #19
0
def discover(current_path, file_pattern='test*.py'):
    """
    I take a path to a directory and discover all the tests inside files
    matching file_pattern.

    If path is not a readable directory, I raise an ImportError.

    If I don't find anything, I return None.  Otherwise I return a
    GreenTestSuite
    """
    current_abspath = os.path.abspath(current_path)
    if not os.path.isdir(current_abspath):
        raise ImportError("'{}' is not a directory".format(str(current_path)))
    suite = GreenTestSuite()
    for file_or_dir_name in sorted(os.listdir(current_abspath)):
        path = os.path.join(current_abspath, file_or_dir_name)
        # Recurse into directories, attempting to skip virtual environments
        if os.path.isdir(path) and not os.path.isfile(
                os.path.join(path, 'bin', 'activate')):
            # Don't follow symlinks
            if os.path.islink(path):
                continue
            # Don't recurse into directories that couldn't be a package name
            if not python_dir_pattern.match(file_or_dir_name):
                continue
            subdir_suite = discover(path, file_pattern=file_pattern)
            if subdir_suite:
                suite.addTest(subdir_suite)

        elif os.path.isfile(path):
            # Skip irrelevant files
            if not python_file_pattern.match(file_or_dir_name):
                continue
            if not fnmatch(file_or_dir_name, file_pattern):
                continue

            # Try loading the file as a module
            module_suite = loadFromModuleFilename(path)
            if module_suite:
                suite.addTest(module_suite)

    return ((suite.countTestCases() and suite) or None)
        def run_tests(self, test_labels, extra_tests=None, **kwargs):
            """
            Run the unit tests for all the test labels in the provided list.

            Test labels should be dotted Python paths to test modules, test
            classes, or test methods.

            A list of 'extra' tests may also be provided; these tests
            will be added to the test suite.

            Returns the number of tests that failed.
            """
            # Django setup
            self.setup_test_environment()
            django_db = self.setup_databases()

            # Green
            if type(test_labels) == tuple:
                test_labels = list(test_labels)
            else:
                raise ValueError("test_labels should be a tuple of strings")
            if not test_labels:
                test_labels = ["."]

            args = mergeConfig(Namespace())
            if self.verbose != -1:
                args.verbose = self.verbose
            args.targets = test_labels
            stream = GreenStream(sys.stdout)
            suite = self.loader.loadTargets(args.targets)
            if not suite:
                suite = GreenTestSuite()
            result = run(suite, stream, args)

            # Django teardown
            self.teardown_databases(django_db)
            self.teardown_test_environment()
            return self.suite_result(suite, result)
Exemple #21
0
def discover(current_path, file_pattern='test*.py'):
    """
    I take a path to a directory and discover all the tests inside files
    matching file_pattern.

    If path is not a readable directory, I raise an ImportError.

    If I don't find anything, I return None.  Otherwise I return a
    GreenTestSuite
    """
    current_abspath = os.path.abspath(current_path)
    if not os.path.isdir(current_abspath):
        raise ImportError(
                "'%s' is not a directory".format(str(current_path)))
    suite = GreenTestSuite()
    for file_or_dir_name in sorted(os.listdir(current_abspath)):
        path = os.path.join(current_abspath, file_or_dir_name)
        # Recurse into directories, attempting to skip virtual environments
        if os.path.isdir(path) and not os.path.isfile(os.path.join(path, 'bin', 'activate')):
            subdir_suite = discover(path, file_pattern=file_pattern)
            if subdir_suite:
                suite.addTest(subdir_suite)

        elif os.path.isfile(path):
            # Skip irrelevant files
            if not python_file_pattern.match(file_or_dir_name):
                continue
            if not fnmatch(file_or_dir_name, file_pattern):
                continue

            # Try loading the file as a module
            module_suite = loadFromModuleFilename(path)
            if module_suite:
                suite.addTest(module_suite)

    return ((suite.countTestCases() and suite) or None)
Exemple #22
0
    debug("Test case names: {}".format(test_case_names))
    test_case_names.sort(
        key=functools.cmp_to_key(lambda x, y: (x > y) - (x < y)))
    if not test_case_names and hasattr(test_case_class, 'runTest'):
        test_case_names = ['runTest']
    return GreenTestSuite(map(test_case_class, test_case_names))


def loadFromModule(module):
    debug("Examining module {} for test cases".format(module.__name__), 2)
    test_cases = []
    for item in dir(module):
        obj = getattr(module, item)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            test_cases.append(loadFromTestCase(obj))
    return GreenTestSuite(test_cases)


def loadFromModuleFilename(filename):
    dotted_module, parent_dir = findDottedModuleAndParentDir(filename)
    # Adding the parent path of the module to the start of sys.path is
    # the closest we can get to an absolute import in Python that I can
    # find.
    sys.path.insert(0, parent_dir)
    try:
        __import__(dotted_module)
        loaded_module = sys.modules[dotted_module]
        debug("Imported {}".format(dotted_module), 2)
    except unittest.case.SkipTest as e:
        # TODO: #25 - Right now this mimics the behavior in unittest.  Lets
        # refactor it and simplify it after we make sure it works.
Exemple #23
0
def suite():
    """ return our TestSuite """
    suite = GreenTestSuite()
    suite = loadFromTestCase(TestConfig)
    return suite
Exemple #24
0
 def test_empty(self):
     """
     An empty suite can be instantiated.
     """
     GreenTestSuite()
Exemple #25
0
 def test_noTestsFound(self):
     """
     When we don't find any tests, we say so.
     """
     run(GreenTestSuite(), self.stream, self.args)
     self.assertIn('No Tests Found', self.stream.getvalue())
Exemple #26
0
def _main(argv, testing):
    args = config.parseArguments(argv)
    args = config.mergeConfig(args, testing)

    if args.shouldExit:
        return args.exitCode

    # Clear out all the passed-in-options just in case someone tries to run a
    # test that assumes sys.argv is clean.  I can't guess at the script name
    # that they want, though, so we'll just leave ours.
    sys.argv = sys.argv[:1]

    # Set up our various main objects
    from green.loader import GreenTestLoader, getCompletions
    from green.runner import run
    from green.output import GreenStream, debug
    import green.output
    from green.suite import GreenTestSuite

    GreenTestSuite.args = args

    if args.debug:
        green.output.debug_level = args.debug

    stream = GreenStream(sys.stdout, disable_windows=args.disable_windows)

    # Location of shell completion file
    if args.completion_file:
        print(os.path.join(os.path.dirname(__file__), "shell_completion.sh"))
        return 0

    # Argument-completion for bash and zsh (for test-target completion)
    if args.completions:
        print(getCompletions(args.targets))
        return 0

    # Option-completion for bash and zsh
    if args.options:
        print("\n".join(sorted(args.store_opt.options)))
        return 0

    # Add debug logging for stuff that happened before this point here
    if config.files_loaded:
        debug("Loaded config file(s): {}".format(", ".join(
            config.files_loaded)))

    # Discover/Load the test suite
    if testing:
        test_suite = None
    else:  # pragma: no cover
        loader = GreenTestLoader()
        test_suite = loader.loadTargets(args.targets,
                                        file_pattern=args.file_pattern)

    # We didn't even load 0 tests...
    if not test_suite:
        debug(
            "No test loading attempts succeeded.  Created an empty test suite."
        )
        test_suite = GreenTestSuite()

    # Actually run the test_suite
    result = run(test_suite, stream, args, testing)

    # Generate a test report if required
    if args.junit_report:
        from green.junit import JUnitXML

        adapter = JUnitXML()
        with open(args.junit_report, "w") as report_file:
            adapter.save_as(result, report_file)

    return int(not result.wasSuccessful())
Exemple #27
0
def loadTarget(target, file_pattern='test*.py'):
    """
    """
    debug("Attempting to load target '{}' with file_pattern '{}'".format(
        target, file_pattern))
    loader = unittest.TestLoader()
    loader.suiteClass = GreenTestSuite

    # For a test loader, we want to always the current working directory to be
    # the first item in sys.path, just like when a python interpreter is loaded
    # interactively.  See also
    # https://docs.python.org/3.4/library/sys.html#sys.path
    if sys.path[0] != '':
        sys.path.insert(0, '')

    # DIRECTORY VARIATIONS - These will discover all tests in a directory
    # structure, whether or not they are accessible by the root package.

    # some/real/dir
    bare_dir = target
    # some.real.dir
    if ('.' in target) and (len(target) > 1):
        dot_dir = target[0] + target[1:].replace('.', os.sep)
    else:
        dot_dir = None
    # pyzmq.tests  (Package (=dir) in PYTHONPATH, including installed ones)
    pkg_in_path_dir = None
    if target and (target[0] != '.'):
        try:
            filename = importlib.import_module(target).__file__
            if '__init__.py' in filename:
                pkg_in_path_dir = os.path.dirname(filename)
        except:
            pkg_in_path_dir = None

    # => DISCOVER DIRS
    tests = None
    for candidate in [bare_dir, dot_dir, pkg_in_path_dir]:
        if (candidate is None) or (not os.path.isdir(candidate)):
            continue
        tests = discover(candidate, file_pattern=file_pattern)
        if tests and tests.countTestCases():
            debug("Load method: DISCOVER - {}".format(candidate))
            return tests

    # DOTTED OBJECT - These will discover a specific object if it is
    # globally importable or importable from the current working directory.
    # Examples: pkg, pkg.module, pkg.module.class, pkg.module.class.func
    tests = None
    if target and (target[0] != '.'):  # We don't handle relative dot objects
        try:
            tests = loader.loadTestsFromName(target)
            for index, test in enumerate(tests):
                if test.__class__.__name__ == '_FailedTest':  # pragma: no cover
                    del (tests._tests[index])

        except Exception as e:
            debug("IGNORED exception: {}".format(e))
        if tests and tests.countTestCases():
            debug("Load method: DOTTED OBJECT - {}".format(target))
            return tests

    # FILE VARIATIONS - These will import a specific file and any tests
    # accessible from its scope.

    # some/file.py
    bare_file = target
    # some/file
    pyless_file = target + '.py'
    for candidate in [bare_file, pyless_file]:
        if (candidate is None) or (not os.path.isfile(candidate)):
            continue
        need_cleanup = False
        cwd = os.getcwd()
        if cwd != sys.path[0]:
            need_cleanup = True
            sys.path.insert(0, cwd)
        try:
            dotted_path = target.replace('.py', '').replace(os.sep, '.')
            tests = loader.loadTestsFromName(dotted_path)
        except:  # Any exception could occur here
            # TODO: #25 - Right now this mimics the behavior in unittest.  Lets
            # refactor it and simplify it after we make sure it works.
            # This is a cause of the traceback mangling I observed.
            try:
                message = ('Failed to import "{}":\n{}').format(
                    dotted_path, traceback.format_exc())
            # If the line that caused the exception has unicode literals in it
            # anywhere, then python 2.7 will crash on traceback.format_exc().
            # Python 3 is ok.
            except UnicodeDecodeError:  # pragma: no cover
                message = ('Failed to import "{}", and the import traceback '
                           'has a unicode decode error, so I can\'t display '
                           'it.'.format(dotted_path))

            def testFailure(self):
                raise ImportError(message)

            TestClass = type(str("ModuleImportFailure"),
                             (unittest.case.TestCase, ),
                             {dotted_path: testFailure})
            return GreenTestSuite((TestClass(dotted_path), ))
        if need_cleanup:
            sys.path.remove(cwd)
        if tests and tests.countTestCases():
            debug("Load method: FILE - {}".format(candidate))
            return tests

    return None
Exemple #28
0
 def test_defaultArgs(self):
     """
     Passing in default arguments causes attributes to be set.
     """
     gts = GreenTestSuite(args=default_args)
     self.assertEqual(gts.allow_stdout, default_args.allow_stdout)