Exemple #1
0
def loadTestsFromModule(self, module, path=None, discovered=False):
    """Load all tests from module and return a suite containing
        them. If the module has been discovered and is not test-like,
        the suite will be empty by default, though plugins may add
        their own tests.
        """
    log.debug("Load from module %s", module)
    tests = []
    test_classes = []
    test_funcs = []
    # For *discovered* modules, we only load tests when the module looks
    # testlike. For modules we've been directed to load, we always
    # look for tests. (discovered is set to True by loadTestsFromDir)
    if not discovered or self.selector.wantModule(module):
        for item in dir(module):
            test = getattr(module, item, None)
            # print "Check %s (%s) in %s" % (item, test, module.__name__)
            if isclass(test):
                if self.selector.wantClass(test):
                    test_classes.append(test)
            elif isfunction(test) and self.selector.wantFunction(test):
                test_funcs.append(test)
        sort_list(test_classes, lambda x: x.__name__)
        sort_list(test_funcs, func_lineno)
        tests = map(lambda t: self.makeTest(t, parent=module),
                    test_classes + test_funcs)

    # Now, descend into packages
    # FIXME can or should this be lazy?
    # is this syntax 2.2 compatible?
    module_paths = getattr(module, '__path__', [])
    if path:
        path = os.path.realpath(path)

    for module_path in module_paths:
        log.debug("Load tests from module path %s?", module_path)
        log.debug("path: %s os.path.realpath(%s): %s", path, module_path,
                  os.path.realpath(module_path))

        # BEGIN MONKEYPATCH
        #If a path was passed in, the case of path and
        #module_path need to be normalized before comparing the two.
        #This is to resolve a Windows-only issue with tests not being
        #discovered correctly for namespace packages.
        if path:
            norm_module_path = os.path.normcase(module_path)
            norm_path = os.path.normcase(path)
        # END MONKEYPATCH

        if (self.config.traverseNamespace or not path) or \
                os.path.realpath(norm_module_path).startswith(norm_path):
            # Egg files can be on sys.path, so make sure the path is a
            # directory before trying to load from it.
            if os.path.isdir(module_path):
                tests.extend(self.loadTestsFromDir(module_path))

    for test in self.config.plugins.loadTestsFromModule(module, path):
        tests.append(test)

    return self.suiteClass(ContextList(tests, context=module))
    def test_context_fixtures_for_ancestors(self):
        top = imp.new_module('top')
        top.bot = imp.new_module('top.bot')
        top.bot.end = imp.new_module('top.bot.end')

        sys.modules['top'] = top
        sys.modules['top.bot'] = top.bot
        sys.modules['top.bot.end'] = top.bot.end

        class TC(unittest.TestCase):
            def runTest(self):
                pass

        top.bot.TC = TC
        TC.__module__ = 'top.bot'

        # suite with just TC test
        # this suite should call top and top.bot setup
        csf = ContextSuiteFactory()
        suite = csf(ContextList([TC()], context=top.bot))

        suite.setUp()
        assert top in csf.was_setup, "Ancestor not set up"
        assert top.bot in csf.was_setup, "Context not set up"
        suite.has_run = True
        suite.tearDown()
        assert top in csf.was_torndown, "Ancestor not torn down"
        assert top.bot in csf.was_torndown, "Context not torn down"

        # wrapped suites
        # the outer suite sets up its context, the inner
        # its context only, without re-setting up the outer context
        csf = ContextSuiteFactory()
        inner_suite = csf(ContextList([TC()], context=top.bot))
        suite = csf(ContextList(inner_suite, context=top))

        suite.setUp()
        assert top in csf.was_setup
        assert not top.bot in csf.was_setup
        inner_suite.setUp()
        assert top in csf.was_setup
        assert top.bot in csf.was_setup
        assert csf.was_setup[top] is suite
        assert csf.was_setup[top.bot] is inner_suite
Exemple #3
0
    def loadTestsFromModule(self, module, discovered=False):
        """Load all tests from module and return a suite containing
        them. If the module has been discovered and is not test-like,
        the suite will be empty by default, though plugins may add
        their own tests.
        """
        log.debug("Load from module %s", module)
        tests = []
        test_classes = []
        test_funcs = []
        # For *discovered* modules, we only load tests when the module looks
        # testlike. For modules we've been directed to load, we always
        # look for tests. (discovered is set to True by loadTestsFromDir)
        if not discovered or self.selector.wantModule(module):
            for item in dir(module):
                test = getattr(module, item, None)
                # print "Check %s (%s) in %s" % (item, test, module.__name__)
                if isclass(test):
                    if self.selector.wantClass(test):
                        test_classes.append(test)
                elif isfunction(test) and self.selector.wantFunction(test):
                    test_funcs.append(test)
            test_classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
            test_funcs.sort(cmp_lineno)
            tests = map(lambda t: self.makeTest(t, parent=module),
                        test_classes + test_funcs)

        # Now, descend into packages
        # FIXME can or should this be lazy?
        # is this syntax 2.2 compatible?
        paths = getattr(module, '__path__', [])
        for path in paths:
            tests.extend(self.loadTestsFromDir(path))
            
        # Catch TypeError and AttributeError exceptions here and discard
        # them: the default plugin manager, NoPlugins, will raise TypeError
        # on generative calls.
        try:
            for test in self.config.plugins.loadTestsFromModule(module):
                tests.append(test)
        except (TypeError, AttributeError):
            pass
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            tests.append(Failure(*sys.exc_info()))

        return self.suiteClass(ContextList(tests, context=module))
Exemple #4
0
    def loadTestsFromModule(self, module, path=None, discovered=False):
        """Load all tests from module and return a suite containing
        them. If the module has been discovered and is not test-like,
        the suite will be empty by default, though plugins may add
        their own tests.
        """
        log.debug("Load from module %s", module)
        tests = []
        test_classes = []
        test_funcs = []
        # For *discovered* modules, we only load tests when the module looks
        # testlike. For modules we've been directed to load, we always
        # look for tests. (discovered is set to True by loadTestsFromDir)
        if not discovered or self.selector.wantModule(module):
            for item in dir(module):
                test = getattr(module, item, None)
                # print "Check %s (%s) in %s" % (item, test, module.__name__)
                if isclass(test):
                    if self.selector.wantClass(test):
                        test_classes.append(test)
                elif isfunction(test) and self.selector.wantFunction(test):
                    test_funcs.append(test)
            sort_list(test_classes, lambda x: x.__name__)
            sort_list(test_funcs, func_lineno)
            tests = [
                self.makeTest(t, parent=module)
                for t in test_classes + test_funcs
            ]

        # Now, descend into packages
        # FIXME can or should this be lazy?
        # is this syntax 2.2 compatible?
        module_paths = getattr(module, '__path__', [])
        if path:
            path = os.path.realpath(path)
        for module_path in module_paths:
            log.debug("Load tests from module path %s?", module_path)
            log.debug("path: %s os.path.realpath(%s): %s", path, module_path,
                      os.path.realpath(module_path))
            if (self.config.traverseNamespace or not path) or \
                    os.path.realpath(module_path).startswith(path):
                tests.extend(self.loadTestsFromDir(module_path))

        for test in self.config.plugins.loadTestsFromModule(module, path):
            tests.append(test)

        return self.suiteClass(ContextList(tests, context=module))
Exemple #5
0
    def loadTestsFromTestClass(self, cls):
        """
        Return tests in this test case class, ordered by phase then by name.
        """
        tests_by_phase = {}
        # Build a mapping of tests to phase
        for test in self.parent_loader.loadTestsFromTestClass(cls):
            test_name = str(test)
            method_name = test_name.split('.')[-1]
            func = getattr(cls, method_name)
            phase = getattr(func, 'phase', 0)
            tests_this_phase = tests_by_phase.setdefault(phase, [])
            tests_this_phase.append((test_name, test))

        # For each phase in order, list out all tests.
        ordered = []
        for phase in sorted(tests_by_phase.keys()):
            for _, test in sorted(tests_by_phase[phase]):
                ordered.append(test)

        return self.suiteClass(ContextList(ordered, context=cls))
Exemple #6
0
    def loadTestsFromModule(self, module, discovered=False):
        """Load all tests from module and return a suite containing
        them. If the module has been discovered and is not test-like,
        the suite will be empty by default, though plugins may add
        their own tests.
        """
        log.debug("Load from module %s", module)
        tests = []
        test_classes = []
        test_funcs = []
        # For *discovered* modules, we only load tests when the module looks
        # testlike. For modules we've been directed to load, we always
        # look for tests. (discovered is set to True by loadTestsFromDir)
        if not discovered or self.selector.wantModule(module):
            for item in dir(module):
                test = getattr(module, item, None)
                # print "Check %s (%s) in %s" % (item, test, module.__name__)
                if isclass(test):
                    if self.selector.wantClass(test):
                        test_classes.append(test)
                elif isfunction(test) and self.selector.wantFunction(test):
                    test_funcs.append(test)
            test_classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
            test_funcs.sort(cmp_lineno)
            tests = map(lambda t: self.makeTest(t, parent=module),
                        test_classes + test_funcs)

        # Now, descend into packages
        # FIXME can or should this be lazy?
        # is this syntax 2.2 compatible?
        paths = getattr(module, '__path__', [])
        for path in paths:
            tests.extend(self.loadTestsFromDir(path))

        for test in self.config.plugins.loadTestsFromModule(module):
            tests.append(test)

        return self.suiteClass(ContextList(tests, context=module))
Exemple #7
0
    def loadTestsFromName(self, name, module=None, discovered=False):
        """Load tests from the entity with the given name.

        The name may indicate a file, directory, module, or any object
        within a module. See `nose.util.split_test_name` for details on
        test name parsing.
        """
        # FIXME refactor this method into little bites?
        log.debug("load from %s (%s)", name, module)

        suite = self.suiteClass

        # give plugins first crack
        plug_tests = self.config.plugins.loadTestsFromName(name, module)
        if plug_tests:
            return suite(plug_tests)

        addr = TestAddress(name, workingDir=self.workingDir)
        if module:
            # Two cases:
            #  name is class.foo
            #    The addr will be incorrect, since it thinks class.foo is
            #    a dotted module name. It's actually a dotted attribute
            #    name. In this case we want to use the full submitted
            #    name as the name to load from the module.
            #  name is module:class.foo
            #    The addr will be correct. The part we want is the part after
            #    the :, which is in addr.call.
            if addr.call:
                name = addr.call
            parent, obj = self.resolve(name, module)
            if (isclass(parent)
                    and getattr(parent, '__module__', None) != module.__name__
                    and not isinstance(obj, Failure)):
                parent = transplant_class(parent, module.__name__)
                obj = getattr(parent, obj.__name__)
            log.debug("parent %s obj %s module %s", parent, obj, module)
            if isinstance(obj, Failure):
                return suite([obj])
            else:
                return suite(
                    ContextList([self.makeTest(obj, parent)], context=parent))
        else:
            if addr.module:
                try:
                    if addr.filename is None:
                        module = resolve_name(addr.module)
                    else:
                        self.config.plugins.beforeImport(
                            addr.filename, addr.module)
                        # FIXME: to support module.name names,
                        # do what resolve-name does and keep trying to
                        # import, popping tail of module into addr.call,
                        # until we either get an import or run out of
                        # module parts
                        try:
                            module = self.importer.importFromPath(
                                addr.filename, addr.module)
                        finally:
                            self.config.plugins.afterImport(
                                addr.filename, addr.module)
                except (KeyboardInterrupt, SystemExit):
                    raise
                except:
                    exc = sys.exc_info()
                    return suite([
                        Failure(exc[0], exc[1], exc[2], address=addr.totuple())
                    ])
                if addr.call:
                    return self.loadTestsFromName(addr.call, module)
                else:
                    return self.loadTestsFromModule(module,
                                                    addr.filename,
                                                    discovered=discovered)
            elif addr.filename:
                path = addr.filename
                if addr.call:
                    package = getpackage(path)
                    if package is None:
                        return suite([
                            Failure(ValueError,
                                    "Can't find callable %s in file %s: "
                                    "file is not a python module" %
                                    (addr.call, path),
                                    address=addr.totuple())
                        ])
                    return self.loadTestsFromName(addr.call, module=package)
                else:
                    if op_isdir(path):
                        # In this case we *can* be lazy since we know
                        # that each module in the dir will be fully
                        # loaded before its tests are executed; we
                        # also know that we're not going to be asked
                        # to load from . and ./some_module.py *as part
                        # of this named test load*
                        return LazySuite(lambda: self.loadTestsFromDir(path))
                    elif op_isfile(path):
                        return self.loadTestsFromFile(path)
                    else:
                        return suite([
                            Failure(OSError,
                                    "No such file %s" % path,
                                    address=addr.totuple())
                        ])
            else:
                # just a function? what to do? I think it can only be
                # handled when module is not None
                return suite([
                    Failure(ValueError,
                            "Unresolvable test name %s" % name,
                            address=addr.totuple())
                ])
Exemple #8
0
        """
        def wanted(attr, cls=cls, sel=self.selector):
            item = getattr(cls, attr, None)
            if isfunction(item):
                item = unbound_method(cls, item)
            elif not ismethod(item):
                return False
            return sel.wantMethod(item)

        cases = [
            self.makeTest(getattr(cls, case), cls)
            for case in filter(wanted, dir(cls))
        ]
        for test in self.config.plugins.loadTestsFromTestClass(cls):
            cases.append(test)
        return self.suiteClass(ContextList(cases, context=cls))

    def makeTest(self, obj, parent=None):
        try:
            return self._makeTest(obj, parent)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            exc = sys.exc_info()
            try:
                addr = test_address(obj)
            except KeyboardInterrupt:
                raise
            except:
                addr = None
            return Failure(exc[0], exc[1], exc[2], address=addr)