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:
holger krekel 2009-10-27 16:49:38 +01:00
commit cc3404b832
6 changed files with 123 additions and 34 deletions

View File

@ -1,7 +1,7 @@
"""nose-compatibility plugin: allow to run nose test suites natively.
This is an experimental plugin for allowing to run tests written
in 'nosetests' style with py.test.
in 'nosetests style with py.test.
Usage
-------------
@ -10,26 +10,32 @@ type::
py.test # instead of 'nosetests'
and you should be able to run nose style tests. You will of course
get py.test style reporting and its feature set.
and you should be able to run nose style tests and at the same
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
and send the resulting URL to a some contact channel.
Known issues
------------------
Unsupported idioms / issues
----------------------------------
- nose-style doctests are not collected and executed correctly,
also fixtures don't work.
- 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 inspect
@ -66,11 +72,14 @@ def pytest_runtest_setup(item):
if isinstance(gen.parent, py.test.collect.Instance):
call_optional(gen.parent.obj, 'setup')
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):
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'):
# #call_optional(item._nosegensetup, 'teardown')
# del item.parent._nosegensetup
@ -82,4 +91,9 @@ def pytest_make_collect_report(collector):
def call_optional(obj, name):
method = getattr(obj, name, None)
if method:
method()
argspec = inspect.getargspec(method)
if argspec[0] == ['self']:
argspec = argspec[1:]
if not any(argspec):
method()
return True

View File

@ -161,13 +161,24 @@ class Module(py.test.collect.File, PyCollectorMixin):
def setup(self):
if getattr(self.obj, 'disabled', 0):
py.test.skip("%r is disabled" %(self.obj,))
mod = self.obj
if hasattr(mod, 'setup_module'):
self.obj.setup_module(mod)
if hasattr(self.obj, 'setup_module'):
#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.setup_module)[0]:
self.obj.setup_module(self.obj)
else:
self.obj.setup_module()
def teardown(self):
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):

View File

@ -1,6 +1,5 @@
import py
import sys
import os, sys
WIDTH = 75
plugins = [
@ -269,6 +268,9 @@ class PluginDoc(RestWriter):
self.Print(opt.help, indent=4)
if __name__ == "__main__":
if os.path.exists("py"):
sys.path.insert(0, os.getcwd())
import py
_config = py.test.config
_config.parse([])
_config.pluginmanager.do_configure(_config)

View File

@ -1,6 +1,10 @@
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
* reshuffle / refine command line grouping

View File

@ -8,7 +8,7 @@ nose-compatibility plugin: allow to run nose test suites natively.
:local:
This is an experimental plugin for allowing to run tests written
in 'nosetests' style with py.test.
in 'nosetests style with py.test.
Usage
-------------
@ -17,25 +17,32 @@ type::
py.test # instead of 'nosetests'
and you should be able to run nose style tests. You will of course
get py.test style reporting and its feature set.
and you should be able to run nose style tests and at the same
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
and send the resulting URL to a some contact channel.
Known issues
------------------
Unsupported idioms / issues
----------------------------------
- nose-style doctests are not collected and executed correctly,
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
=========================================

View File

@ -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*",
])