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