Changeset 113
- Timestamp:
- Mon Nov 13 17:06:48 2006
- Files:
-
- trunk/unit_tests/test_suite.py (added)
- trunk/unit_tests/test_loader.py (modified) (diff)
- trunk/nose/core.py (modified) (diff)
- trunk/nose/suite.py (modified) (diff)
- trunk/nose/importer.py (modified) (diff)
- trunk/nose/loader.py (modified) (diff)
- trunk/nose/selector.py (modified) (diff)
- trunk/nose/proxy.py (modified) (diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
trunk/unit_tests/test_loader.py
r93 r113 248 248 249 249 if __name__ == '__main__': 250 #import logging 251 #logging.basicConfig() 252 #logging.getLogger('').setLevel(0) 253 unittest.main(testLoader=loader.TestLoader()) 250 import logging 251 logging.basicConfig() 252 logging.getLogger('').setLevel(0) 253 #logging.getLogger('nose.importer').setLevel(0) 254 unittest.main() #testLoader=loader.TestLoader()) -
trunk/nose/core.py
r96 r113 15 15 from nose.proxy import ResultProxySuite 16 16 from nose.result import Result 17 from nose.suite import LazySuite , TestModule17 from nose.suite import LazySuite 17 17 from nose.util import absdir, tolist 18 18 from nose.importer import add_path … … 469 469 testLoader = defaultTestLoader(conf) 470 470 def collector(conf, loader): 471 return TestModule(loader.loadTestsFromModule, conf,name)471 return loader.loadTestsFromModule(name=name) 471 471 main(defaultTest=collector, testLoader=testLoader) 472 472 -
trunk/nose/suite.py
r86 r113 4 4 """ 5 5 import logging 6 import os 6 7 import sys 7 8 import unittest … … 13 14 log = logging.getLogger('nose.suite') 14 15 15 16 class LazySuite(unittest.TestSuite): 17 """Generator-based test suite. Pass a callable that returns an iterable of 18 tests, and a nose.config.Config. Also provides hooks (setUp and tearDown) 19 for suite-level fixtures. 16 class TestSuite(unittest.TestSuite): 17 """A test suite with setup and teardown methods. 20 18 """ 21 # _exc_info_to_string needs this property22 failureException = unittest.TestCase.failureException23 24 def __init__(self, loadtests, conf=None):25 self._loadtests = loadtests26 if conf is None:27 conf = Config()28 self.conf = conf29 30 def loadtests(self):31 for test in self._loadtests():32 yield test33 34 # lazy property so subclasses can override loadtests()35 _tests = property(lambda self: self.loadtests(),36 None, None,37 'Tests in this suite (iter)')38 39 19 def __call__(self, *arg, **kw): 40 20 self.run(*arg, **kw) 21 22 def id(self): 23 return self.__str__() 41 24 42 25 def run(self, result): … … 64 47 finally: 65 48 result.stopTest(self) 66 49 66 49 def setUp(self): 67 50 pass … … 75 58 76 59 60 class ModuleSuite(TestSuite): 61 """Suite of tests in a module. 62 """ 63 def __init__(self, tests, module=None, error=None, **kw): 64 super(ModuleSuite, self).__init__(tests=tests, **kw) 65 self.module = module 66 self.error = error 67 68 def __repr__(self): 69 try: 70 name = self.module.__name__ 71 if hasattr(self.module, '__path__') and self.module.__path__: 72 path = self.module.__path__[0] 73 else: 74 path = self.module.__file__ 75 for i in xrange(0, len(name.split('.'))): 76 path = os.path.dirname(path) 77 return "test module %s in %s" % (name, path) 78 except AttributeError: 79 from traceback import format_exception 80 if self.error: 81 ef = ''.join(format_exception(*self.error)) 82 else: 83 ef = '' 84 return "test module (%s, %s)" % (self.module, ef) 85 __str__ = __repr__ 86 87 def run(self, result): 88 if self.error: 89 result.addError(self.error) 90 return 91 # Don't bother running setup and teardown if we don't 92 # have any tests to run. 93 if not self._tests: 94 return 95 super(ModuleSuite, self).run(result) 96 97 def setUp(self): 98 """Run any package or module setup function found. For packages, setup 99 functions may be named 'setupPackage', 'setup_package', 'setUp', 100 or 'setup'. For modules, setup functions may be named 101 'setupModule', 'setup_module', 'setUp', or 'setup'. The setup 102 function may optionally accept a single argument; in that case, 103 the test package or module will be passed to the setup function. 104 """ 105 log.debug('TestModule.setUp') 106 if hasattr(self.module, '__path__'): 107 names = ['setupPackage', 'setUpPackage', 'setup_package'] 108 else: 109 names = ['setupModule', 'setUpModule', 'setup_module'] 110 names += ['setUp', 'setup'] 111 try_run(self.module, names) 112 113 def tearDown(self): 114 """Run any package or module teardown function found. For packages, 115 teardown functions may be named 'teardownPackage', 116 'teardown_package' or 'teardown'. For modules, teardown functions 117 may be named 'teardownModule', 'teardown_module' or 118 'teardown'. The teardown function may optionally accept a single 119 argument; in that case, the test package or module will be passed 120 to the teardown function. 121 122 The teardown function will be run only if any package or module 123 setup function completed successfully. 124 """ 125 if hasattr(self.module, '__path__'): 126 names = ['teardownPackage', 'teardown_package'] 127 else: 128 names = ['teardownModule', 'teardown_module'] 129 names += ['tearDown', 'teardown'] 130 try_run(self.module, names) 131 132 # backwards compatibility 133 TestModule = ModuleSuite 134 135 136 class LazySuite(TestSuite): 137 """Generator-based test suite. Pass a callable that returns an iterable of 138 tests, and a nose.config.Config. Also provides hooks (setUp and tearDown) 139 for suite-level fixtures. 140 """ 141 # _exc_info_to_string needs this property 142 failureException = unittest.TestCase.failureException 143 144 def __init__(self, loadtests, conf=None, **kw): 145 self._loadtests = loadtests 146 if conf is None: 147 conf = Config() 148 self.conf = conf 149 150 def loadtests(self): 151 for test in self._loadtests(): 152 yield test 153 154 # lazy property so subclasses can override loadtests() 155 _tests = property(lambda self: self.loadtests(), 156 None, None, 157 'Tests in this suite (iter)') 158 159 77 160 class GeneratorMethodTestSuite(LazySuite): 78 161 """Test suite for test methods that are generators. … … 134 217 self.importPath): 135 218 yield test 136 137 138 class TestModule(LazySuite):139 """Lazy suite that collects tests from modules and packages.140 141 This suite collects module members that match the testMatch142 regular expression. For packages, it also collects any modules or143 packages found in the package __path__ that match testMatch. For144 modules that themselves do not match testMatch, the collector collects145 doctests instead of test functions.146 147 Before returning the first collected test, any defined setup method148 will be run. Packages may define setup, setUp, setup_package or149 setUpPackage, modules setup, setUp, setup_module, setupModule or150 setUpModule. Likewise, teardown will be run if defined and if setup151 ran successfully; teardown methods follow the same naming rules as152 setup methods.153 """154 fromDirectory = None155 156 def __init__(self, loadtests, conf, moduleName=None, path=None,157 module=None):158 self.moduleName = moduleName159 self.path = path160 self.module = module161 if module and moduleName is None:162 self.moduleName = module.__name__163 LazySuite.__init__(self, loadtests, conf)164 165 def __repr__(self):166 return "test module %s in %s" % (self.moduleName, self.path)167 __str__ = __repr__168 169 def loadtests(self):170 tests = self._loadtests(self.module, self.path)171 try:172 for test in tests:173 yield test174 except TypeError:175 # python 2.3: TestSuite not iterable176 for test in tests._tests:177 yield test178 179 def id(self):180 return self.__str__()181 182 def setUp(self):183 """Run any package or module setup function found. For packages, setup184 functions may be named 'setupPackage', 'setup_package', 'setUp',185 or 'setup'. For modules, setup functions may be named186 'setupModule', 'setup_module', 'setUp', or 'setup'. The setup187 function may optionally accept a single argument; in that case,188 the test package or module will be passed to the setup function.189 """190 log.debug('TestModule.setUp')191 if self.module is None:192 self.module = _import(self.moduleName, [self.path], self.conf)193 log.debug('Imported %s from %s on %s', self.module,194 self.moduleName, self.path)195 if hasattr(self.module, '__path__'):196 names = ['setupPackage', 'setUpPackage', 'setup_package']197 else:198 names = ['setupModule', 'setUpModule', 'setup_module']199 names += ['setUp', 'setup']200 try_run(self.module, names)201 202 def tearDown(self):203 """Run any package or module teardown function found. For packages,204 teardown functions may be named 'teardownPackage',205 'teardown_package' or 'teardown'. For modules, teardown functions206 may be named 'teardownModule', 'teardown_module' or207 'teardown'. The teardown function may optionally accept a single208 argument; in that case, the test package or module will be passed209 to the teardown function.210 211 The teardown function will be run only if any package or module212 setup function completed successfully.213 """214 if hasattr(self.module, '__path__'):215 names = ['teardownPackage', 'teardown_package']216 else:217 names = ['teardownModule', 'teardown_module']218 names += ['tearDown', 'teardown']219 try_run(self.module, names) -
trunk/nose/importer.py
r86 r113 43 43 if conf.addPaths: 44 44 for p in path: 45 add_path(p) 45 if p is not None: 46 add_path(p) 46 47 47 48 path = [ p for p in path if p is not None ] -
trunk/nose/loader.py
r93 r113 10 10 from nose.case import * 11 11 from nose.config import Config 12 from nose.importer import add_path 12 from nose.importer import add_path, _import 12 12 from nose.plugins import call_plugins 13 13 from nose.selector import defaultSelector 14 from nose.suite import LazySuite, TestClass, TestDir, TestModule, \14 from nose.suite import ModuleSuite, TestClass, TestDir, \ 14 14 GeneratorMethodTestSuite 15 15 from nose.util import is_generator, split_test_name, try_run … … 19 19 log = logging.getLogger(__name__) 20 20 21 class LoaderException(Exception): 22 pass 21 23 22 24 class TestLoader(unittest.TestLoader): … … 30 32 long as possible. 31 33 """ 34 suiteClass = ModuleSuite 35 32 36 def __init__(self, conf=None, selector=None): 33 37 if conf is None: … … 52 56 "absolute paths (%s)" % dirname) 53 57 self.conf.working_dir = dirname 54 58 if importPath is None: 59 importPath = dirname 60 55 61 # Ensure that any directory we examine is on sys.path 56 62 if self.conf.addPaths: … … 78 84 yield test 79 85 80 def loadTestsFromModule(self, module, importPath=None): 81 """Load tests from module at (optional) import path. 86 def loadTestsFromModule(self, module=None, name=None, 87 package=None, importPath=None): 88 """Load tests from module at (optional) import path. One of module or 89 name must be supplied. If name is supplied, the module name (prepended 90 with package if that is not empty) will be imported. 82 91 """ 92 if module is None: 93 if name is None: 94 raise LoaderException("loadTestsFromModule: one of module or " 95 "name must be supplied") 96 if package is not None: 97 modname = "%s.%s" % (package, name) 98 else: 99 modname = name 100 try: 101 log.debug("Importing %s from %s", modname, importPath) 102 module = _import(modname, [importPath], self.conf) 103 except KeyboardInterrupt: 104 raise 105 except: 106 error = sys.exc_info() 107 return self.suiteClass(tests=[], error=error) 108 83 109 log.debug("load from module %s (%s)", module, importPath) 84 110 tests = [] … … 105 131 module.__name__, importPath)) 106 132 # compat w/unittest 107 return self.suiteClass(tests) 108 109 def loadTestsFromModuleName(self, module_name, package=None, 110 importPath=None): 111 """Load tests from module_name. Specifiy module (name) to load module 112 from that module. Specify import path 113 to import from that path. 114 """ 115 if package is not None: 116 module_name = "%s.%s" % (package, module_name) 117 if importPath is None: 118 importPath = self.conf.working_dir 119 yield TestModule(self.loadTestsFromModule, 120 self.conf, module_name, importPath) 133 return self.suiteClass(tests, module=module) 121 134 122 135 def loadTestsFromName(self, name, module=None, importPath=None): … … 131 144 except AttributeError: 132 145 pass 146 147 if importPath is None: 148 importPath = self.conf.working_dir 133 149 134 150 tests = None … … 161 177 elif mod_name: 162 178 # handle module-like names 163 tests = self.loadTestsFromModuleName(name, 164 package=module, 165 importPath=importPath) 179 log.debug("%s is a module name", name) 180 yield self.loadTestsFromModule(name=name, 181 package=module, 182 importPath=importPath) 166 183 elif module: 167 184 # handle func-like names in a module … … 169 186 if tests: 170 187 for test in tests: 171 yield test 188 yield test 171 188 # give plugins a chance 172 189 for plug in self.plugins: … … 194 211 self.conf.tests.extend([ rel(n, module.__name__) 195 212 for n in names ]) 196 197 213 try: 198 214 mpath = os.path.dirname(module.__path__[0]) … … 200 216 mpath = os.path.dirname(module.__file__) 201 217 202 #return self.loadTestsFromModule(module) 203 return TestModule(self.loadTestsFromModule, 204 self.conf, 205 module=module, 206 path=mpath) 218 return self.loadTestsFromModule(module, importPath=mpath) 207 219 else: 208 220 tests = [] 209 221 for name in names: 210 222 for test in self.loadTestsFromName(name): 211 tests.append(test) 223 tests.append(test) 211 223 return self.suiteClass(tests) 212 224 … … 230 242 ispymod = False 231 243 if ispymod: 232 if module is not None: 233 test = "%s.%s" % (module, test) 234 yield TestModule(self.loadTestsFromModule, 235 self.conf, test, importPath) 244 yield self.loadTestsFromModule(name=test, package=module, 245 importPath=importPath) 236 246 # give plugins a chance 237 247 for plug in self.plugins: -
trunk/nose/selector.py
r104 r113 210 210 """Is the directory a wanted test directory? 211 211 212 All package directories match, so long as they do not match exclude. All 213 other directories must match test requirements. 212 All package directories match, so long as they do not match exclude. 213 All other directories must match test requirements. 214 214 """ 215 215 init = os.path.join(dirname, '__init__.py') -
trunk/nose/proxy.py
r62 r113 10 10 import unittest 11 11 from nose.result import Result, ln 12 from nose.suite import TestSuite 12 13 13 14 log = logging.getLogger(__name__) … … 69 70 70 71 71 class ResultProxySuite( unittest.TestSuite):72 class ResultProxySuite(TestSuite): 71 72 """Test suite that supports output capture, etc, by wrapping each test in 72 73 a TestProxy.
