Changeset 20
- Timestamp:
- Thu Apr 6 21:57:13 2006
- Files:
-
- trunk/nose/core.py (modified) (diff)
- trunk/nose/suite.py (modified) (diff)
- trunk/nose/plugins/doctests.py (modified) (diff)
- trunk/nose/plugins/base.py (modified) (diff)
- trunk/nose/plugins/__init__.py (modified) (diff)
- trunk/nose/plugins/profile.py (modified) (diff)
- trunk/nose/plugins/missed.py (modified) (diff)
- trunk/nose/__init__.py (modified) (diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
trunk/nose/core.py
r18 r20 1 """Implements core nose test discovery functions.1 """Implements nose test program and collector. 1 1 """ 2 2 import logging … … 15 15 from nose.loader import defaultTestLoader 16 16 from nose.selector import defaultSelector 17 from nose.suite import LazySuite 17 from nose.suite import LazySuite, ResultProxySuite 17 17 from nose.util import absdir, absfile, try_run 18 18 … … 22 22 23 23 class TestCollector(LazySuite): 24 """ Discovery-based test suite. FIXME docs out of date24 """Main nose test collector. 24 24 25 Unless told not to, the collector looks in the current directory for 26 test packages, modules, or directories and creates test suites to run 27 all tests in any found. A list of tests to run may also be specified. 28 29 Test modules, packages or directories are: 30 * Any directory with 'test' in the name (will be loaded as a test 31 package if it contains an __init__.py file, otherwise as a test 32 directory) 33 * And file with 'test' in the name (will be loaded as a test module) 25 Uses a test loader to load tests from the directory given in conf 26 (conf.path). Uses the default test loader from nose.loader by 27 default. Any other loader may be used so long as it implements 28 loadTestsFromDir(). 34 29 """ 35 30 … … 55 50 def collector(): 56 51 """TestSuite replacement entry point. Use anywhere you might use a 57 unittest.TestSuite. Note: Except with testoob; currently (nose 0. 8)52 unittest.TestSuite. Note: Except with testoob; currently (nose 0.9) 57 52 testoob's test loading is not compatible with nose's collector 58 53 implementation. 54 55 Returns a TestCollector configured to use a TestLoader that returns 56 ResultProxySuite test suites, which use a proxy result object to 57 enable output capture and assert introspection. 59 58 """ 59 # FIXME somehow restrict plugin methods 60 60 conf = configure(env=os.environ) 61 result.install_patch(conf) 62 63 # FIXME if any plugin implements prepareTest, here must patch 64 # unittest.TextTestRunner.run with run like nose's TextTestRunner 65 return TestCollector(conf) 61 loader = defaultTestLoader(conf) 62 loader.suiteClass = ResultProxySuite 63 return TestCollector(conf, loader) 66 64 67 65 68 66 class TextTestRunner(unittest.TextTestRunner): 69 67 """Test runner that uses nose's TextTestResult to enable output 68 capture and assert introspection, as well as providing hooks for 69 plugins to override or replace the test output stream, results, and 70 the test case itself. 71 """ 70 72 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1, 71 73 conf=None): … … 106 108 directories and packages found in its working directory (which 107 109 defaults to the current working directory). Any python source file, 108 directory or package that matches nose.core.testMatch (by default: 109 (?:^|[\b_\.-])[Tt]est) will be collected as a test (or source for 110 collection of tests). In addition, all other packages found in the 111 working directory are examined for python source files or directories 112 that match nose.core.testMatch. Package discovery descends all the way 113 down the tree, so package.tests and package.sub.tests and 110 directory or package that matches the testMatch regulat expression 111 (by default: (?:^|[\b_\.-])[Tt]est) will be collected as a test (or 112 source for collection of tests). In addition, all other packages 113 found in the working directory are examined for python source files 114 or directories that match testMatch. Package discovery descends all 115 the way down the tree, so package.tests and package.sub.tests and 114 116 package.sub.sub2.tests will all be collected. 115 117 116 118 Within a test directory or package, any python source file matching 117 nose.core.testMatch will be examined for test cases. Within a test 118 file, functions with 'test' in the name and TestCase subclasses (with 119 any name) will be loaded and executed as tests. Functional tests may 120 use the assert keyword or raise AssertionErrors to indicate test 121 failure; TestCase subclasses may do the same or use the various 119 testMatch will be examined for test cases. Within a test file, 120 functions and classes whose names match testMatch and TestCase 121 subclasses with any name will be loaded and executed as tests. Tests 122 may use the assert keyword or raise AssertionErrors to indicate test 123 failure. TestCase subclasses may do the same or use the various 122 124 TestCase methods available. 123 124 Some options may also be set by env variables. For those options, the 125 env variable appears in brackets at the end of the option 126 description. Command line settings will override environment settings. 127 125 126 Tests may raise nose.SkipTest to indicate that they should be 127 skipped or nose.DeprecatedTest to indicate that they are 128 deprecated. Skipped and deprecated tests do not count as failures, 129 but details on them are printed at the end of the test run along 130 with any failures and erorrs. 131 128 132 Selecting Tests 129 133 --------------- 130 134 131 To specify additional tests to run, beyond those found in discovery, pass 132 test names on the command line:: 135 To specify which tests to run, pass test names on the command line:: 133 136 134 %prog also_this.py137 %prog only_test_this.py 134 137 135 (FIXME -- update test selection notes to new selector/test address syntax) 138 Test names specified may be file or module names, and may optionally 139 indicate the test case to run by separating the module or file name 140 from the test case name with a colon. Examples:: 141 142 %prog test.module 143 %prog another.test:TestCase.test_method 144 %prog a.test:TestCase 145 %prog /path/to/test/file.py:test_function 146 147 Note however that specifying a test name will *not* cause nose to run 148 a test that it does not discover. Test names specified are compared 149 against tests discovered, and only the requested tests are 150 run. Setup and teardown methods are run at all stages. That means 151 that if you run:: 152 153 %prog some.tests.test_module:test_function 154 155 And have defined setup or teardown methods in tests and test_module, 156 those setup methods will run before the test_function test, and 157 teardown after, just as if you were running all tests. 136 158 137 159 You may also change the working directory where nose looks for tests, … … 140 162 141 163 %prog -w /path/to/tests 164 165 Further customization of test selection and loading is possible 166 through the use of plugins. 142 167 """ 143 168 verbosity = 1 … … 246 271 help="Don't make any changes to sys.path when " 247 272 "loading tests [NOSE_NOPATH]") 248 249 273 250 274 # add opts from plugins … … 350 374 351 375 def main(*arg, **kw): 352 """ Collect and run test, returning success or failure376 """Run and exit with 0 on success or 1 on failure. 352 376 """ 353 return TestProgram(*arg, **kw).success377 return sys.exit(not run(*arg, **kw)) 353 377 378 # backwards compatibility 379 run_exit = main 354 380 355 def run_exit(*arg, **kw): 356 """Run main() and exit with 0 on success or 1 on failure. 381 def run(*arg, **kw): 382 """Collect and run test, returning success or failure 357 383 """ 358 sys.exit(not main(*arg, **kw))384 return TestProgram(*arg, **kw).success 358 384 359 385 360 # FIXME move to util386 # FIXME move to tools? 360 386 def with_setup(setup=None, teardown=None): 361 387 """Decorator to add setup and/or teardown methods to a test function -
trunk/nose/suite.py
r18 r20 61 61 pass 62 62 63 64 class ResultProxySuite(LazySuite): 65 pass 66 63 67 64 68 class TestClass(LazySuite): -
trunk/nose/plugins/doctests.py
r15 r20 24 24 25 25 class Doctest(Plugin): 26 """Activate doctest plugin to find and run doctest in non-test modules. 26 """ 27 Activate doctest plugin to find and run doctest in non-test modules. 27 28 """ 28 29 extension = None -
trunk/nose/plugins/base.py
r18 r20 80 80 return list(val) 81 81 82 82 83 class PluginInterface(object): 83 84 """ … … 98 99 and returns a non-None value wins, and plugin processing ends. The 99 100 only exceptions to are `loadTestsFromModule`, `loadTestsFromName`, 100 and `loadTestsFromPath`, which allow multiple plugins to load tests. 101 and `loadTestsFromPath`, which allow multiple plugins to load and 102 return tests. 101 103 102 104 In general, plugin methods correspond directly to the methods of 103 105 nose.selector.Selector, nose.loader.TestLoader and 104 nose.result.TextTestResult where they are called. In some cases, the 105 plugin hook doesn't neatly match the method in which it is called; 106 for those, the documentation for the hook will tell you where in the 107 test process it is available. 106 nose.result.TextTestResult are called by those methods when they are 107 called. In some cases, the plugin hook doesn't neatly match the 108 method in which it is called; for those, the documentation for the 109 hook will tell you where in the test process it is called. 108 110 109 111 Plugin hooks fall into two broad categories: selecting and loading -
trunk/nose/plugins/__init__.py
r18 r20 40 40 that want the standard options should call the superclass methods. 41 41 42 defining command-line and environment options 42 nose uses optparse.OptionParser from the standard library to parse 43 arguments. A plugin's add_options() method receives a parser 44 instance. It's good form for a plugin to use that instance only to add 45 additional arguments that take only long arguments (--like-this). Most 46 of nose's built-in arguments get their default value from an environment 47 variable. This is a good practice because it allows options to be 48 utilized when run through some other means than the nosetests script. 49 50 A plugin's configure() receives the parsed OptionParser options object, 51 as well as the current config object. Plugins should configure their 52 behavior based on the user-selected settings, and may raise exceptions 53 if the configured behavior is nonsensical. 43 54 44 configuring from selected options 55 Logging 56 ======= 45 57 46 logging 58 nose uses the logging classes from the standard library. To enable users 59 to view debug messages easily, plugins should use logging.getLogger() to 60 acquire a logger in the 'nose.plugins' namespace. 47 61 48 62 Recipes … … 90 104 91 105 See nose.plugins.attrib, nose.plugins.cover, nose.plugins.doctests and 92 nose.plugins.profile for examples. 93 94 examples in examples/ dir... 106 nose.plugins.profile for examples. Further examples may be found the 107 examples directory in the nose source distribution. 95 108 """ 96 109 import logging -
trunk/nose/plugins/profile.py
r17 r20 1 """FIXME module docs 1 """Use the profile plugin with --with-profile or NOSE_WITH_PROFILE to 2 enable profiling using the hotshot profiler. Profiler output can be 3 controlled with the --profile-sort and --profile-restrict, and the 4 profiler output file may be changed with --profile-stats-file. 2 5 3 FIXME change module name to profiler to avoid conflict w/builtin profile.py 6 See the hotshot documentation in the standard library documentation for 7 more details on the various output options. 4 8 """ 5 9 … … 12 16 13 17 class Profile(Plugin): 14 """FIXME usage help 18 """ 19 Use this plugin to run tests using the hotshot profiler. 15 20 """ 16 21 def add_options(self, parser, env=os.environ): … … 42 47 else: 43 48 # FIXME use a temp file 44 self.pfile = ' FIXME'49 self.pfile = 'nose.profile' 44 49 self.sort = options.profile_sort 45 50 self.restrict = self.tolist(options.profile_restrict) -
trunk/nose/plugins/missed.py
r18 r20 3 3 4 4 class MissedTests(Plugin): 5 """Enable to get a warning when tests specified on the command line 5 """ 6 Enable to get a warning when tests specified on the command line 6 7 are not found during the test run. 7 8 """ … … 18 19 for missed in self.missed: 19 20 result.stream.writeln("WARNING: missed test '%s'" % missed) 20 21 def startTest(self, test):22 if not self.missed:23 return24 found = []25 for name in self.missed:26 if self.match(test, name):27 found.append(name)28 for name in found:29 self.missed.remove(name)30 21 31 22 def match(self, test, test_name): … … 49 40 return False 50 41 return True 42 43 def startTest(self, test): 44 if not self.missed: 45 return 46 found = [] 47 for name in self.missed: 48 if self.match(test, name): 49 found.append(name) 50 for name in found: 51 self.missed.remove(name) -
trunk/nose/__init__.py
r14 r20 17 17 nose.main() 18 18 19 If you want the test script to exit with 0 on success and 1 on failure 20 (like unittest.main), use nose.run_exit() instead:: 19 If you don't want the test script to exit with 0 on success and 1 on failure 20 (like unittest.main), use nose.run() instead:: 21 21 22 22 import nose 23 nose.run _exit()23 nose.run() 23 23 24 Lastly, you can nose.core directly::24 Lastly, you can run nose.core directly, which will run nose.main():: 24 24 25 25 python /path/to/nose/core.py 26 26 27 27 Please see the usage message for the nosetests script for information 28 about how to control which tests nose runs and the test output. 28 about how to control which tests nose runs, which plugins are loaded, 29 and the test output. 29 30 30 31 Features … … 49 50 because teardown has not yet run at the time of the failure.) 50 51 51 When running as a setup command, output capture is implemented by52 patching nose's test result class into unittest.53 54 52 Assert introspection 55 53 ==================== … … 67 65 assert a == 4, "assert 2 is 4" 68 66 69 You will get output somethinglike::67 You will get output like:: 69 67 70 68 File "/path/to/file.py", line XX, in test_integers: … … 73 71 InspectAssertionError: assert 2 is 4 74 72 >> assert 2 == 4, "assert 2 is 4" 75 76 When running as a setuptools command, assert introspection is77 implemented by patching nose's test result class into unittest.78 73 79 74 Setuptools integration … … 94 89 When running under setuptools, you can configure nose settings via the 95 90 environment variables detailed in the nosetests script usage message. 96 91 92 Please note that when run under setuptools, some plugins will not be 93 available, including the builtin coverage, profiler, and missed test 94 plugins. 95 96 nose 1.0 will include a custom setuptools command that will enable all 97 plugins available when running nosetests. 98 97 99 .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools 98 100 … … 200 202 =============== 201 203 202 nose supports test functions that are generators. A simple example from nose's 203 selftest suite is probably the best explanation:: 204 nose supports test functions and methods that are generators. A simple 205 example from nose's selftest suite is probably the best explanation:: 204 206 205 207 def test_evens(): … … 244 246 -------------------- 245 247 246 nose was inspired mainly by py.test_, which is far more functional than 247 nose, but is not all that easy to install, and is not based on unittest. 248 nose was inspired mainly by py.test_, which is a great test runner, but 249 formerly was not all that easy to install, and is not based on unittest. 248 250 249 251 TestGears_ is a similar test runner (now part of TurboGears) that was … … 277 279 along with this program; if not, write to the Free Software Foundation, 278 280 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 279 280 TODO281 282 * Docstrings for all classes283 * Output better shortDescription()s284 281 """ 285 282
