def addError(self, test, err): """ Add error to the test result :param test: Test for which to add error :type test: str :param error: Error message to add :type error: str """ if isclass(err[0]) and issubclass(err[0], TCThresholdReached): return if isclass(err[0]) and issubclass(err[0], SkipTest): self.addSkip(test, err[1]) return if isclass(err[0]) and issubclass(err[0], TimeOut): self.addTimedOut(test, err) return for cls, (storage, label, isfail) in self.errorClasses.items(): if isclass(err[0]) and issubclass(err[0], cls): if isfail: test.passed = False storage.append((test, err)) if self.showAll: self.logger.info(label + '\n') elif self.dots: self.logger.info(label[0]) return test.passed = False self._addError(test, err)
def test_isclass_detects_classes(self): class TC(unittest.TestCase): pass class TC_Classic: pass class TC_object(object): pass # issue153 -- was not detecting custom typed classes... class TCType(type): pass class TC_custom_type(object): __metaclass__ = TCType class TC_unittest_custom_type(unittest.TestCase): __metaclass__ = TCType assert util.isclass(TC), "failed to detect %s as class" % TC assert util.isclass(TC_Classic), "failed to detect %s as class" % TC_Classic assert util.isclass(TC_object), "failed to detect %s as class" % TC_object assert util.isclass(TC_custom_type), "failed to detect %s as class" % TC_custom_type assert util.isclass(TC_unittest_custom_type), "failed to detect %s as class" % TC_unittest_custom_type
def test_isclass_detects_classes(self): class TC(unittest.TestCase): pass class TC_Classic: pass class TC_object(object): pass # issue153 -- was not detecting custom typed classes... class TCType(type): pass class TC_custom_type(object): __metaclass__ = TCType class TC_unittest_custom_type(unittest.TestCase): __metaclass__ = TCType assert util.isclass(TC), "failed to detect %s as class" % TC assert util.isclass( TC_Classic), "failed to detect %s as class" % TC_Classic assert util.isclass( TC_object), "failed to detect %s as class" % TC_object assert util.isclass( TC_custom_type), "failed to detect %s as class" % TC_custom_type assert util.isclass( TC_unittest_custom_type ), "failed to detect %s as class" % TC_unittest_custom_type
def addBlocked(self, test, err, context): """Overrides normal addBlocked to add support for errorClasses. If the exception is a registered class, the error will be added to the list for that class, not errors. """ ec, ev, tb = err for cls, (_, label, isfail) in self.errorClasses.items(): # if 'Skip' in cls.__name__ or 'Skip' in ec.__name__: # from nose.tools import set_trace # set_trace() if isclass(ec) and issubclass(ec, cls): if isfail: test.passed = False s = self.blocked.setdefault(label, []) s.append((test, err, context)) self.printLabel(label, err) return if isclass(ec) and issubclass(ec, test.failureException): label = "FAIL" else: label = "ERROR" storage = self.blocked.setdefault(label, []) storage.append((test, err, context)) test.passed = False self.printLabel(label)
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 addError(self, test, err): """ Add error """ if isclass(err[0]) and issubclass(err[0], TCThresholdReached): return True self.__set_test_end_data(test, err)
def addError(self, test, err): """Overrides normal addError to add support for errorClasses. If the exception is a registered class, the error will be added to the list for that class, not errors. """ stream = getattr(self, 'stream', None) ec, ev, tb = err try: exc_info = self._exc_info_to_string(err, test) except TypeError: # 2.3 compat exc_info = self._exc_info_to_string(err) for cls, (storage, label, isfail) in self.errorClasses.items(): if isclass(ec) and issubclass(ec, cls): storage.append((test, exc_info)) # Might get patched into a streamless result if stream is not None: if self.showAll: stream.writeln(label) elif self.dots: stream.write(label[:1]) return self.errors.append((test, exc_info)) if stream is not None: if self.showAll: self.stream.writeln('ERROR') elif self.dots: stream.write('E')
def _recordAndPrintHeadline(self, test, error_class, artifact): """Record that an error-like thing occurred, and print a summary. Store ``artifact`` with the record. Return whether the test result is any sort of failure. """ # We duplicate the errorclass handling from super rather than calling # it and monkeying around with showAll flags to keep it from printing # anything. is_error_class = False for cls, (storage, label, is_failure) in self.errorClasses.items(): if isclass(error_class) and issubclass(error_class, cls): if is_failure: test.passed = False storage.append((test, artifact)) is_error_class = True if not is_error_class: self.errors.append((test, artifact)) test.passed = False is_any_failure = not is_error_class or is_failure self._printHeadline(label if is_error_class else 'ERROR', test, is_failure=is_any_failure) return is_any_failure
def _recordAndPrintHeadline(self, test, error_class, artifact): """Record that an error-like thing occurred, and print a summary. Store ``artifact`` with the record. Return whether the test result is any sort of failure. """ # We duplicate the errorclass handling from super rather than calling # it and monkeying around with showAll flags to keep it from printing # anything. is_error_class = False for cls, (storage, label, is_failure) in self.errorClasses.iteritems(): if isclass(error_class) and issubclass(error_class, cls): if is_failure: test.passed = False storage.append((test, artifact)) is_error_class = True if not is_error_class: self.errors.append((test, artifact)) test.passed = False is_any_failure = not is_error_class or is_failure self._printHeadline(label if is_error_class else 'ERROR', test, is_failure=is_any_failure) return is_any_failure
def addError(self, test, err): err_cls, a, b = err if not isclass(err_cls): return classes = [e[0] for e in self.errorClasses] if [c for c in classes if issubclass(err_cls, c)]: return True
def makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ ldr = loader.TestLoader() if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): # Randomize the order of the tests in the TestCase return self.randomized_loadTestsFromTestCase(obj) else: return self.randomized_loadTestsFromTestClass(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return parent(obj.__name__) else: if isgenerator(obj): return ldr.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_func(obj, parent.__name__) if isgenerator(obj): return ldr.loadTestsFromGenerator(obj, parent) else: return [FunctionTestCase(obj)] else: return Failure(TypeError, "Can't make a test from %s" % obj)
def addError(self, test, error): # pylint: disable-msg=W0221 """Overrides normal addError to add support for errorClasses. If the exception is a registered class, the error will be added to the list for that class, not errors. """ fixTestCase(test) #manually call startTest if it's not already called if not getattr(test, '_subunit_started', False): self.startTest(test) ecls, evt, tbk = error # pylint: disable-msg=W0612 # pylint: disable-msg=W0612 for cls, (storage, label, isfail) in self.errorClasses.items(): if isclass(ecls) and issubclass(ecls, cls): if not isfail: reason = _exception_detail(evt) if reason and self.useDetails: details = {"reason":TextContent(reason)} reason = None else: details = None self._addNonFailOutcome(label.lower(), test, reason=reason, details=details) return self._wassuccess = False error, details = self._getArgs(test, error) test.passed = False TestProtocolClient.addError(self, test, error, details=details)
def addError(self, test, err): err_cls, a, b = err if not isclass(err_cls): return classes = [e[0] for e in self.errorClasses] if filter(lambda c: issubclass(err_cls, c), classes): return True
def _makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ plug_tests = [] try: addr = test_address(obj) except KeyboardInterrupt: raise except: addr = None for test in self.config.plugins.makeTest(obj, parent): plug_tests.append(test) # TODO: is this try/except needed? try: if plug_tests: return self.suiteClass(plug_tests) except (KeyboardInterrupt, SystemExit): raise except: exc = sys.exc_info() return Failure(exc[0], exc[1], exc[2], address=addr) if isfunction(obj) and parent and not isinstance(parent, types.ModuleType): # This is a Python 3.x 'unbound method'. Wrap it with its # associated class.. obj = unbound_method(parent, obj) if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): return self.loadTestsFromTestCase(obj) else: return self.loadTestsFromTestClass(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return parent(obj.__name__) else: if isgenerator(obj): return self.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): isgen = isgenerator(obj) if parent and obj.__module__ != parent.__name__: obj = transplant_func(obj, parent.__name__) if isgen: return self.loadTestsFromGenerator(obj, parent) else: return FunctionTestCase(obj) else: return Failure(TypeError, "Can't make a test from %s" % obj, address=addr)
def _makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ plug_tests = [] try: addr = test_address(obj) except KeyboardInterrupt: raise except: addr = None for test in self.config.plugins.makeTest(obj, parent): plug_tests.append(test) # TODO: is this try/except needed? try: if plug_tests: return self.suiteClass(plug_tests) except (KeyboardInterrupt, SystemExit): raise except: exc = sys.exc_info() return Failure(exc[0], exc[1], exc[2], address=addr) if isfunction(obj) and parent and not isinstance( parent, types.ModuleType): # This is a Python 3.x 'unbound method'. Wrap it with its # associated class.. obj = unbound_method(parent, obj) if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): return self.loadTestsFromTestCase(obj) else: return self.loadTestsFromTestClass(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return parent(obj.__name__) else: if isgenerator(obj): return self.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_func(obj, parent.__name__) if isgenerator(obj): return self.loadTestsFromGenerator(obj, parent) else: return FunctionTestCase(obj) else: return Failure(TypeError, "Can't make a test from %s" % obj, address=addr)
def _exc_info_to_string(self, err, test=None): from nose.plugins.skip import SkipTest if isclass(err[0]) and issubclass(err[0], SkipTest): return str(err[1]) try: return _TextTestResult._exc_info_to_string(self, err, test) except TypeError: # 2.3: does not take test arg return _TextTestResult._exc_info_to_string(self, err)
def addError(self, test, err): if isclass(err[0]) and issubclass(err[0], SkipTest): self.addSkip(test, err[1]) return if isclass(err[0]) and issubclass(err[0], TimeOut): self.addTimedOut(test, err) return for cls, (storage, label, isfail) in self.errorClasses.items(): if isclass(err[0]) and issubclass(err[0], cls): if isfail: test.passed = False storage.append((test, err)) if self.showAll: self.logger.info(label + '\n') elif self.dots: self.logger.info(label[0]) return test.passed = False self._addError(test, err)
def _exc_info_to_string(self, err, test=None): # 2.7 skip compat from nose.plugins.skip import SkipTest if isclass(err[0]) and issubclass(err[0], SkipTest): return str(err[1]) # 2.3/2.4 -- 2.4 passes test, 2.3 does not try: return _TextTestResult._exc_info_to_string(self, err, test) except TypeError: # 2.3: does not take test arg return _TextTestResult._exc_info_to_string(self, err)
def startContext(self, context): context.param = self.param context.start_time = datetime.datetime.now() if isclass(context) and issubclass(context, PBSTestSuite): self.result.logger.info(self.result.separator1) self.result.logger.info('suite name: ' + context.__name__) doc = context.__doc__ if doc is not None: self.result.logger.info('suite docstring: \n' + doc + '\n') self.result.logger.info(self.result.separator1) context.start_time = datetime.datetime.now()
def startContext(self, context): if self.options.syncplan: if isclass(context): names = ContextSuite.classSetup + ContextSuite.classTeardown else: names = ContextSuite.moduleSetup + ContextSuite.moduleTeardown if hasattr(context, '__path__'): names += ContextSuite.packageSetup + ContextSuite.packageTeardown # If my context has any fixture attribute, I have fixtures for m in names: if hasattr(context, m): setattr(context, m, None)
def startContext(self, context): context.param = self.param context.start_time = datetime.datetime.now() if isclass(context) and issubclass(context, unittest.TestCase): self.result.logger.info(self.result.separator1) self.result.logger.info('suite name: ' + context.__name__) doc = context.__doc__ if doc is not None: self.result.logger.info('suite docstring: \n' + doc + '\n') self.result.logger.info(self.result.separator1) self.__failed_tc_count = 0 self.__failed_tc_count_msg = False
def filter_no_plugins(module): name = MODULE_PREFIX + ".%s" % module try: module = __import__(name, fromlist=[PLUGIN_CLASS_NAME]) module_attrs = dir(module) if 'OutputPlugin' in module_attrs: plugin = getattr(module, PLUGIN_CLASS_NAME) if isclass(plugin): return True except ImportError, e: str_reason = traceback.format_exc(e) return False
def _determineSetupRoutine(self): context = self.context if isclass(context): names = self.classSetup else: names = self.moduleSetup if hasattr(context, '__path__'): names = self.packageSetup + names for name in names: func = getattr(context, name, None) if callable(func): return func return self.setUp
def _determineTeardownRoutine(self): context = self.context if isclass(context): names = self.classTeardown else: names = self.moduleTeardown if hasattr(context, '__path__'): names = self.packageTeardown + names for name in names: func = getattr(context, name, None) if callable(func): return func return self.tearDown
def teardownContext(self, context): log.debug("%s teardown context %s", self, context) if self.factory: if context in self.factory.was_torndown: return self.factory.was_torndown[context] = self if isclass(context): names = self.classTeardown else: names = self.moduleTeardown if hasattr(context, '__path__'): names = self.packageTeardown + names try_run(context, names) self.config.plugins.stopContext(context)
def makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ ldr = loader.TestLoader() if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if not self.class_specific: if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): # Randomize the order of the tests in the TestCase return self.randomized_loadTestsFromTestCase(obj) else: return self.randomized_loadTestsFromTestClass(obj) else: class_specific_seed = getattr( obj, CLASS_SPECIFIC_RANDOMIZE_TESTS_FIELD_NAME, None) if issubclass( obj, unittest.TestCase) and class_specific_seed is not None: random.seed(class_specific_seed) print("Using %d as seed to randomize tests in %s" % (class_specific_seed, '.'.join( [obj.__module__, obj.__name__]))) return self.randomized_loadTestsFromTestCase(obj) else: return ldr.loadTestsFromTestCase(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return parent(obj.__name__) else: if isgenerator(obj): return ldr.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_func(obj, parent.__name__) if isgenerator(obj): return ldr.loadTestsFromGenerator(obj, parent) else: return [FunctionTestCase(obj)] else: return Failure(TypeError, "Can't make a test from %s" % obj)
def teardownContext(self, context): log.debug("%s teardown context %s", self, context) if self.factory: self.factory.was_torndown[context] = self if isclass(context): names = ('teardown_class', 'teardown_all', 'teardownClass', 'teardownAll', 'tearDownClass', 'tearDownAll') else: names = ('teardown_module', 'teardownModule', 'tearDownModule', 'teardown') if hasattr(context, '__path__'): names = ('teardown_package', 'teardownPackage', 'tearDownPackage') + names try_run(context, names) self.config.plugins.stopContext(context)
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 setupContext(self, context): self.config.plugins.startContext(context) log.debug("%s setup context %s", self, context) if self.factory: if context in self.factory.was_setup: return # note that I ran the setup for this context, so that I'll run # the teardown in my teardown self.factory.was_setup[context] = self if isclass(context): names = self.classSetup else: names = self.moduleSetup if hasattr(context, '__path__'): names = self.packageSetup + names try_run(context, names)
def setupContext(self, context): self.config.plugins.startContext(context) log.debug("%s setup context %s", self, context) if self.factory: # note that I ran the setup for this context, so that I'll run # the teardown in my teardown self.factory.was_setup[context] = self if isclass(context): names = ('setup_class', 'setup_all', 'setupClass', 'setupAll', 'setUpClass', 'setUpAll') else: names = ('setup_module', 'setupModule', 'setUpModule', 'setup') if hasattr(context, '__path__'): names = ('setup_package', 'setupPackage', 'setUpPackage') + names try_run(context, names)
def implementsAnyFixture(self, context, ctx_callback): if isclass(context): names = self.classSetup + self.classTeardown else: names = self.moduleSetup + self.moduleTeardown if hasattr(context, '__path__'): names += self.packageSetup + self.packageTeardown # If my context has any fixture attribute, I have fixtures fixt = False for m in names: if hasattr(context, m): fixt = True break if ctx_callback is None: return fixt return ctx_callback(context, fixt)
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 makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ ldr = loader.TestLoader() if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if not self.class_specific: if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): # Randomize the order of the tests in the TestCase return self.randomized_loadTestsFromTestCase(obj) else: return self.randomized_loadTestsFromTestClass(obj) else: class_specific_seed = getattr(obj, CLASS_SPECIFIC_RANDOMIZE_TESTS_FIELD_NAME, None) if issubclass(obj, unittest.TestCase) and class_specific_seed is not None: random.seed(class_specific_seed) print("Using %d as seed to randomize tests in %s" % (class_specific_seed, '.'.join( [obj.__module__, obj.__name__]))) return self.randomized_loadTestsFromTestCase(obj) else: return ldr.loadTestsFromTestCase(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return [parent(obj.__name__)] else: if isgenerator(obj): return ldr.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_func(obj, parent.__name__) if isgenerator(obj): return ldr.loadTestsFromGenerator(obj, parent) else: return [FunctionTestCase(obj)] else: return Failure(TypeError, "Can't make a test from %s" % obj)
def makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): # Sort the tests according to their dependencies return self.Dependency_loadTestsFromTestCase(obj) else: raise Exception("All tests must derive from unittest.TestCase to work with dependency_tests plugin") else: raise Exception("All tests must derive from unittest.TestCase to work with dependency_tests plugin")
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)) 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 makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ # Catch TypeError and AttributeError exceptions here and discard # them: the default plugin manager, NoPlugins, will raise TypeError # on generative calls. plug_tests = [] try: for test in self.config.plugins.makeTest(obj, parent): plug_tests.append(test) if plug_tests: return self.suiteClass(plug_tests) except (TypeError, AttributeError): pass except (KeyboardInterrupt, SystemExit): raise except: return Failure(*sys.exc_info()) if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if issubclass(obj, unittest.TestCase): return self.loadTestsFromTestCase(obj) else: return self.loadTestsFromTestClass(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return parent(obj.__name__) else: if isgenerator(obj): return self.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): if isgenerator(obj): return self.loadTestsFromGenerator(obj, parent) else: return FunctionTestCase(obj) else: return Failure(TypeError, "Can't make a test from %s" % obj)
def makeTest(self, obj, parent=None): """Given a test object and its parent, return a test case or test suite. """ plug_tests = [] for test in self.config.plugins.makeTest(obj, parent): plug_tests.append(test) # TODO: is this try/except needed? try: if plug_tests: return self.suiteClass(plug_tests) except (KeyboardInterrupt, SystemExit): raise except: return Failure(*sys.exc_info()) if isinstance(obj, unittest.TestCase): return obj elif isclass(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_class(obj, parent.__name__) if issubclass(obj, unittest.TestCase): return self.loadTestsFromTestCase(obj) else: return self.loadTestsFromTestClass(obj) elif ismethod(obj): if parent is None: parent = obj.__class__ if issubclass(parent, unittest.TestCase): return parent(obj.__name__) else: if isgenerator(obj): return self.loadTestsFromGeneratorMethod(obj, parent) else: return MethodTestCase(obj) elif isfunction(obj): if parent and obj.__module__ != parent.__name__: obj = transplant_func(obj, parent.__name__) if isgenerator(obj): return self.loadTestsFromGenerator(obj, parent) else: return FunctionTestCase(obj) else: return Failure(TypeError, "Can't make a test from %s" % obj)
def __init__(self, config=None, importer=None, workingDir=None, selector=None): """Initialize a test loader. Parameters (all optional): * config: provide a `nose.config.Config`_ or other config class instance; if not provided a `nose.config.Config`_ with default values is used. * importer: provide an importer instance that implements `importFromPath`. If not provided, a `nose.importer.Importer`_ is used. * workingDir: the directory to which file and module names are relative. If not provided, assumed to be the current working directory. * selector: a selector class or instance. If a class is provided, it will be instantiated with one argument, the current config. If not provided, a `nose.selector.Selector`_ is used. """ if config is None: config = Config() if importer is None: importer = Importer(config=config) if workingDir is None: workingDir = config.workingDir if selector is None: selector = defaultSelector(config) elif isclass(selector): selector = selector(config) self.config = config self.importer = importer self.workingDir = op_normpath(op_abspath(workingDir)) self.selector = selector if config.addPaths: add_path(workingDir, config) self.suiteClass = ContextSuiteFactory(config=config) self._visitedPaths = set([]) unittest.TestLoader.__init__(self)
def test_address(self, test): if hasattr(test, "address"): return test.address()[0] t = type(test) file = None import types, os if (t == types.FunctionType or issubclass(t, type) or t == type or isclass(test)): module = getattr(test, '__module__', None) if module is not None: m = sys.modules[module] file = getattr(m, '__file__', None) if file is not None: file = os.path.abspath(file) if file.endswith("pyc"): file = file[:-1] return file raise TypeError("I don't know what %s is (%s)" % (test, t))
def addError(self, test, err): """Overrides normal addError to add support for errorClasses. If the exception is a registered class, the error will be added to the list for that class, not errors. """ ec, ev, tb = err try: exc_info = self._exc_info_to_string(err, test) except TypeError: exc_info = self._exc_info_to_string(err) for cls, (storage, label, isfail) in self.errorClasses.items(): if isclass(ec) and issubclass(ec, cls): if isfail: test.passed = False storage.append((test, exc_info)) self.printLabel(label, err) return self.errors.append((test, exc_info)) test.passed = False self.printLabel('ERROR')
def parseArgs(self, argv): """Parse argv and env and configure running environment. """ self.config.configure(argv, doc=self.usage()) log.debug("configured %s", self.config) # quick outs: version, plugins (optparse would have already # caught and exited on help) if self.config.options.version: from nose import __version__ sys.stdout = sys.__stdout__ print("%s version %s" % (os.path.basename(sys.argv[0]), __version__)) sys.exit(0) if self.config.options.showPlugins: self.showPlugins() sys.exit(0) if self.testLoader is None: self.testLoader = defaultTestLoader(config=self.config) elif isclass(self.testLoader): self.testLoader = self.testLoader(config=self.config) plug_loader = self.config.plugins.prepareTestLoader(self.testLoader) if plug_loader is not None: self.testLoader = plug_loader log.debug("test loader is %s", self.testLoader) # FIXME if self.module is a string, add it to self.testNames? not sure if self.config.testNames: self.testNames = self.config.testNames else: self.testNames = tolist(self.defaultTest) log.debug('defaultTest %s', self.defaultTest) log.debug('Test names are %s', self.testNames) if self.config.workingDir is not None: os.chdir(self.config.workingDir) self.createTests()
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))