merged ronny's nose-compatibility hacks, i.e. nosestyle
setup_module() and setup() functions are supported. added a few notes to changelog and documentation about it --HG-- branch : trunk
This commit is contained in:
		
						commit
						cc3404b832
					
				|  | @ -1,7 +1,7 @@ | ||||||
| """nose-compatibility plugin: allow to run nose test suites natively.  | """nose-compatibility plugin: allow to run nose test suites natively.  | ||||||
| 
 | 
 | ||||||
| This is an experimental plugin for allowing to run tests written  | This is an experimental plugin for allowing to run tests written  | ||||||
| in 'nosetests' style with py.test.   | in 'nosetests style with py.test.    | ||||||
| 
 | 
 | ||||||
| Usage | Usage | ||||||
| ------------- | ------------- | ||||||
|  | @ -10,26 +10,32 @@ type:: | ||||||
| 
 | 
 | ||||||
|     py.test  # instead of 'nosetests' |     py.test  # instead of 'nosetests' | ||||||
| 
 | 
 | ||||||
| and you should be able to run nose style tests.  You will of course  | and you should be able to run nose style tests and at the same | ||||||
| get py.test style reporting and its feature set.  | time can make full use of py.test's capabilities.   | ||||||
| 
 | 
 | ||||||
| Issues?  | Supported nose Idioms | ||||||
| ---------------- | ---------------------- | ||||||
| 
 | 
 | ||||||
| If you find issues or have suggestions please run::  | * setup and teardown at module/class/method level | ||||||
|  | * SkipTest exceptions and markers  | ||||||
|  | * setup/teardown decorators | ||||||
|  | * yield-based tests and their setup  | ||||||
|  | * general usage of nose utilities  | ||||||
| 
 | 
 | ||||||
|     py.test --pastebin=all  | Unsupported idioms / issues | ||||||
| 
 | ---------------------------------- | ||||||
| and send the resulting URL to a some contact channel.  |  | ||||||
| 
 |  | ||||||
| Known issues  |  | ||||||
| ------------------ |  | ||||||
| 
 | 
 | ||||||
| - nose-style doctests are not collected and executed correctly, | - nose-style doctests are not collected and executed correctly, | ||||||
|   also fixtures don't work.  |   also fixtures don't work.  | ||||||
| 
 | 
 | ||||||
| - no nose-configuration is recognized  | - no nose-configuration is recognized  | ||||||
| 
 | 
 | ||||||
|  | If you find other issues or have suggestions please run::  | ||||||
|  | 
 | ||||||
|  |     py.test --pastebin=all  | ||||||
|  | 
 | ||||||
|  | and send the resulting URL to a py.test contact channel, | ||||||
|  | at best to the mailing list.  | ||||||
| """ | """ | ||||||
| import py | import py | ||||||
| import inspect | import inspect | ||||||
|  | @ -66,11 +72,14 @@ def pytest_runtest_setup(item): | ||||||
|                 if isinstance(gen.parent, py.test.collect.Instance): |                 if isinstance(gen.parent, py.test.collect.Instance): | ||||||
|                     call_optional(gen.parent.obj, 'setup') |                     call_optional(gen.parent.obj, 'setup') | ||||||
|                 gen._nosegensetup = True |                 gen._nosegensetup = True | ||||||
|         call_optional(item.obj, 'setup') |         if not call_optional(item.obj, 'setup'): | ||||||
|  |             # call module level setup if there is no object level one | ||||||
|  |             call_optional(item.parent.obj, 'setup') | ||||||
| 
 | 
 | ||||||
| def pytest_runtest_teardown(item): | def pytest_runtest_teardown(item): | ||||||
|     if isinstance(item, py.test.collect.Function): |     if isinstance(item, py.test.collect.Function): | ||||||
|         call_optional(item.obj, 'teardown') |         if not call_optional(item.obj, 'teardown'): | ||||||
|  |             call_optional(item.parent.obj, 'teardown') | ||||||
|         #if hasattr(item.parent, '_nosegensetup'): |         #if hasattr(item.parent, '_nosegensetup'): | ||||||
|         #    #call_optional(item._nosegensetup, 'teardown') |         #    #call_optional(item._nosegensetup, 'teardown') | ||||||
|         #    del item.parent._nosegensetup |         #    del item.parent._nosegensetup | ||||||
|  | @ -82,4 +91,9 @@ def pytest_make_collect_report(collector): | ||||||
| def call_optional(obj, name): | def call_optional(obj, name): | ||||||
|     method = getattr(obj, name, None) |     method = getattr(obj, name, None) | ||||||
|     if method: |     if method: | ||||||
|         method() |         argspec = inspect.getargspec(method) | ||||||
|  |         if argspec[0] == ['self']: | ||||||
|  |             argspec = argspec[1:] | ||||||
|  |         if not any(argspec): | ||||||
|  |             method() | ||||||
|  |             return True | ||||||
|  |  | ||||||
|  | @ -161,13 +161,24 @@ class Module(py.test.collect.File, PyCollectorMixin): | ||||||
|     def setup(self):  |     def setup(self):  | ||||||
|         if getattr(self.obj, 'disabled', 0): |         if getattr(self.obj, 'disabled', 0): | ||||||
|             py.test.skip("%r is disabled" %(self.obj,)) |             py.test.skip("%r is disabled" %(self.obj,)) | ||||||
|         mod = self.obj |         if hasattr(self.obj, 'setup_module'):  | ||||||
|         if hasattr(mod, 'setup_module'):  |             #XXX: nose compat hack, move to nose plugin | ||||||
|             self.obj.setup_module(mod) |             # if it takes a positional arg, its probably a py.test style one | ||||||
|  |             # so we pass the current module object | ||||||
|  |             if inspect.getargspec(self.obj.setup_module)[0]: | ||||||
|  |                 self.obj.setup_module(self.obj) | ||||||
|  |             else: | ||||||
|  |                 self.obj.setup_module() | ||||||
| 
 | 
 | ||||||
|     def teardown(self):  |     def teardown(self):  | ||||||
|         if hasattr(self.obj, 'teardown_module'):  |         if hasattr(self.obj, 'teardown_module'):  | ||||||
|             self.obj.teardown_module(self.obj)  |             #XXX: nose compat hack, move to nose plugin | ||||||
|  |             # if it takes a positional arg, its probably a py.test style one | ||||||
|  |             # so we pass the current module object | ||||||
|  |             if inspect.getargspec(self.obj.teardown_module)[0]: | ||||||
|  |                 self.obj.teardown_module(self.obj) | ||||||
|  |             else: | ||||||
|  |                 self.obj.teardown_module() | ||||||
| 
 | 
 | ||||||
| class Class(PyCollectorMixin, py.test.collect.Collector):  | class Class(PyCollectorMixin, py.test.collect.Collector):  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| 
 | 
 | ||||||
| import py | import os, sys | ||||||
| import sys |  | ||||||
| WIDTH = 75 | WIDTH = 75 | ||||||
| 
 | 
 | ||||||
| plugins = [ | plugins = [ | ||||||
|  | @ -269,6 +268,9 @@ class PluginDoc(RestWriter): | ||||||
|             self.Print(opt.help, indent=4) |             self.Print(opt.help, indent=4) | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|  |     if os.path.exists("py"): | ||||||
|  |         sys.path.insert(0, os.getcwd()) | ||||||
|  |     import py | ||||||
|     _config = py.test.config |     _config = py.test.config | ||||||
|     _config.parse([]) |     _config.parse([]) | ||||||
|     _config.pluginmanager.do_configure(_config) |     _config.pluginmanager.do_configure(_config) | ||||||
|  |  | ||||||
|  | @ -1,6 +1,10 @@ | ||||||
| Changes between 1.0.2 and '1.1.0b1' | Changes between 1.0.2 and '1.1.0b1' | ||||||
| ===================================== | ===================================== | ||||||
| 
 | 
 | ||||||
|  | * merged Ronny's nose-compatibility hacks: now | ||||||
|  |   nose-style setup_module() and setup() functions are  | ||||||
|  |   supported | ||||||
|  | 
 | ||||||
| * introduce generalized py.test.mark function marking | * introduce generalized py.test.mark function marking | ||||||
| 
 | 
 | ||||||
| * reshuffle / refine command line grouping | * reshuffle / refine command line grouping | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ nose-compatibility plugin: allow to run nose test suites natively. | ||||||
|   :local: |   :local: | ||||||
| 
 | 
 | ||||||
| This is an experimental plugin for allowing to run tests written  | This is an experimental plugin for allowing to run tests written  | ||||||
| in 'nosetests' style with py.test.   | in 'nosetests style with py.test.    | ||||||
| 
 | 
 | ||||||
| Usage | Usage | ||||||
| ------------- | ------------- | ||||||
|  | @ -17,25 +17,32 @@ type:: | ||||||
| 
 | 
 | ||||||
|     py.test  # instead of 'nosetests' |     py.test  # instead of 'nosetests' | ||||||
| 
 | 
 | ||||||
| and you should be able to run nose style tests.  You will of course  | and you should be able to run nose style tests and at the same | ||||||
| get py.test style reporting and its feature set.  | time can make full use of py.test's capabilities.   | ||||||
| 
 | 
 | ||||||
| Issues?  | Supported nose Idioms | ||||||
| ---------------- | ---------------------- | ||||||
| 
 | 
 | ||||||
| If you find issues or have suggestions please run::  | * setup and teardown at module/class/method level | ||||||
|  | * SkipTest exceptions and markers  | ||||||
|  | * setup/teardown decorators | ||||||
|  | * yield-based tests and their setup  | ||||||
|  | * general usage of nose utilities  | ||||||
| 
 | 
 | ||||||
|     py.test --pastebin=all  | Unsupported idioms / issues | ||||||
| 
 | ---------------------------------- | ||||||
| and send the resulting URL to a some contact channel.  |  | ||||||
| 
 |  | ||||||
| Known issues  |  | ||||||
| ------------------ |  | ||||||
| 
 | 
 | ||||||
| - nose-style doctests are not collected and executed correctly, | - nose-style doctests are not collected and executed correctly, | ||||||
|   also fixtures don't work.  |   also fixtures don't work.  | ||||||
| 
 | 
 | ||||||
| - no nose-configuration is recognized | - no nose-configuration is recognized  | ||||||
|  | 
 | ||||||
|  | If you find other issues or have suggestions please run::  | ||||||
|  | 
 | ||||||
|  |     py.test --pastebin=all  | ||||||
|  | 
 | ||||||
|  | and send the resulting URL to a py.test contact channel, | ||||||
|  | at best to the mailing list. | ||||||
| 
 | 
 | ||||||
| Start improving this plugin in 30 seconds | Start improving this plugin in 30 seconds | ||||||
| ========================================= | ========================================= | ||||||
|  |  | ||||||
|  | @ -85,3 +85,54 @@ def test_nose_test_generator_fixtures(testdir): | ||||||
|     ]) |     ]) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | def test_module_level_setup(testdir): | ||||||
|  |     testdir.makepyfile(""" | ||||||
|  |         from nose.tools import with_setup | ||||||
|  |         items = {} | ||||||
|  |         def setup(): | ||||||
|  |             items[1]=1 | ||||||
|  | 
 | ||||||
|  |         def teardown(): | ||||||
|  |             del items[1] | ||||||
|  | 
 | ||||||
|  |         def setup2(): | ||||||
|  |             items[2] = 2 | ||||||
|  | 
 | ||||||
|  |         def teardown2(): | ||||||
|  |             del items[2] | ||||||
|  | 
 | ||||||
|  |         def test_setup_module_setup(): | ||||||
|  |             assert items[1] == 1 | ||||||
|  | 
 | ||||||
|  |         @with_setup(setup2, teardown2) | ||||||
|  |         def test_local_setup(): | ||||||
|  |             assert items[2] == 2 | ||||||
|  |             assert 1 not in items | ||||||
|  | 
 | ||||||
|  |     """) | ||||||
|  |     result = testdir.runpytest('-p', 'nose') | ||||||
|  |     result.stdout.fnmatch_lines([ | ||||||
|  |         "*2 passed*", | ||||||
|  |     ]) | ||||||
|  | 
 | ||||||
|  | def test_nose_style_setup_teardown(testdir): | ||||||
|  |     testdir.makepyfile(""" | ||||||
|  |         l = [] | ||||||
|  |         def setup_module(): | ||||||
|  |             l.append(1) | ||||||
|  | 
 | ||||||
|  |         def teardown_module(): | ||||||
|  |             del l[0] | ||||||
|  | 
 | ||||||
|  |         def test_hello(): | ||||||
|  |             assert l == [1] | ||||||
|  | 
 | ||||||
|  |         def test_world(): | ||||||
|  |             assert l == [1] | ||||||
|  |         """) | ||||||
|  |     result = testdir.runpytest('-p', 'nose') | ||||||
|  |     result.stdout.fnmatch_lines([ | ||||||
|  |         "*2 passed*", | ||||||
|  |     ]) | ||||||
|  | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue