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
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))
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))
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))
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))
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()) ])
""" 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)