[svn r63990] * adding XXXed funcargs docs, moving release announcements to own subdir
--HG-- branch : trunk
This commit is contained in:
parent
7cc9419ab0
commit
9f30ca6688
|
@ -7,6 +7,6 @@ Contents:
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release-1.0.0
|
||||
release-0.9.2
|
||||
release-0.9.0
|
||||
announce/release-1.0.0
|
||||
announce/release-0.9.2
|
||||
announce/release-0.9.0
|
||||
|
|
|
@ -110,6 +110,11 @@ name. Given a filesystem ``fspath`` it is constructed as follows:
|
|||
Plugin hooks and events
|
||||
=======================================
|
||||
|
||||
See definitions at
|
||||
.. automodule:: py.__.test.plugin.api
|
||||
|
||||
.. autoclass:: PluginHooks
|
||||
:members:
|
||||
|
||||
.. autoclass:: Events
|
||||
:members:
|
||||
|
||||
http://codespeak.net/svn/py/trunk/py/test/plugin/api.py
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
|
||||
=====================================
|
||||
Python test function arguments
|
||||
=====================================
|
||||
|
||||
py.test enables a new way to separate test configuration
|
||||
and test setup from actual test code in test functions.
|
||||
When it runs a test functions it will lookup function
|
||||
arguments by name and provide a value.
|
||||
Here is a simple example for such a test function:
|
||||
|
||||
def test_function(mysetup):
|
||||
# work with mysetup
|
||||
|
||||
To provide a value py.test looks for a ``pytest_funcargs``
|
||||
dictionary in the test module, for example::
|
||||
|
||||
class MySetup:
|
||||
def __init__(self, pyfuncitem):
|
||||
self.pyfuncitem = pyfuncitem
|
||||
pytest_funcargs = {'mysetup': MySetup}
|
||||
|
||||
This is already enough to run the test. Of course
|
||||
up until now our ``mysetup`` does not provide
|
||||
much value. But it is now easy to add new
|
||||
methods on the ``MySetup`` class that have
|
||||
full access to the test collection process.
|
||||
|
||||
Plugins can register their funcargs via
|
||||
the config object, usually upon initial configure::
|
||||
|
||||
class ConftestPlugin:
|
||||
def pytest_configure(self, config):
|
||||
config.register_funcargs(mysetup=MySetup)
|
||||
|
||||
If you provide a "funcarg" from a plugin you can
|
||||
easily make methods depend on command line options
|
||||
or environment settings. Here is a complete
|
||||
example that allows to run tests involving
|
||||
an SSH connection if an ssh host is specified::
|
||||
|
||||
class ConftestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
parser.addoption("--ssh", action="store", default=None,
|
||||
help="specify ssh host to run tests with")
|
||||
|
||||
def pytest_configure(self, config):
|
||||
config.register_funcargs(mysetup=MySetup)
|
||||
|
||||
class MySetup:
|
||||
def __init__(self, pyfuncitem):
|
||||
self.pyfuncitem = pyfuncitem
|
||||
def ssh_gateway(self):
|
||||
host = pyfuncitem.config.option.ssh
|
||||
if host is None:
|
||||
py.test.skip("specify ssh host with --ssh to run this test")
|
||||
return py.execnet.SshGateway(host)
|
||||
|
||||
Now any test functions can use the "mysetup" object, for example::
|
||||
|
||||
class TestClass:
|
||||
def test_function(self, mysetup):
|
||||
ssh_gw = mysetup.ssh_gateway()
|
||||
# work with ssh_gw
|
||||
|
||||
Without specifying a command line option the output looks like this::
|
||||
|
||||
...
|
||||
|
||||
|
||||
Lookup rules
|
||||
======================
|
||||
|
||||
In order to run this test function a value for the
|
||||
``mysetup`` needs to be found. Here is how py.test
|
||||
finds a matching provider function:
|
||||
|
||||
1. see if there is a ``pytest_funcargs`` dictionary
|
||||
which maps ``mysetup`` to a provider function.
|
||||
if so, call the provider function.
|
||||
|
||||
XXX
|
||||
|
||||
|
||||
|
||||
example
|
||||
=====================
|
||||
|
||||
You can run a test file ``test_some.py`` with this content:
|
||||
|
||||
pytest_funcargs = {'myarg': (lambda pyfuncitem: 42)}
|
||||
|
||||
def test_something(myarg):
|
||||
assert myarg == 42
|
||||
|
||||
You can also put this on a class:
|
||||
|
||||
class TestClass:
|
||||
pytest_funcargs = {'myarg': (lambda pyfuncitem: 42)}
|
||||
|
||||
def test_something(self, myarg):
|
||||
assert myarg == 42
|
||||
|
||||
To separate funcarg setup you can also put a funcarg
|
||||
definition into a conftest.py::
|
||||
|
||||
pytest_funcargs = {'myarg': decorate_myarg}
|
||||
def decorate_myarg(pyfuncitem):
|
||||
result = pyfuncitem.call_next_provider()
|
||||
return result + 1
|
||||
|
||||
for registering funcargs from a plugin, talk to the
|
||||
test configuration object like this::
|
||||
|
||||
class MyPlugin:
|
||||
def pytest_configure(self, config):
|
||||
config.register_funcargs(
|
||||
myarg=decorate_myarg
|
||||
)
|
||||
|
||||
a local helper funcarg for doing acceptance tests maybe
|
||||
by running shell commands could look like this::
|
||||
|
||||
class MyPlugin:
|
||||
def pytest_option(self, parser):
|
||||
group = parser.addgroup("myproject acceptance tests")
|
||||
group.addoption("-A", dest="acceptance", action="store_true",
|
||||
help="run (slow) acceptance tests")
|
||||
|
||||
def pytest_configure(self, config):
|
||||
config.register_funcargs(accept=AcceptFuncarg)
|
||||
|
||||
class AcceptFuncarg:
|
||||
def __init__(self, pyfuncitem):
|
||||
if not pyfuncitem.config.option.acceptance:
|
||||
py.test.skip("specify -A to run acceptance tests")
|
||||
self.tmpdir = pyfuncitem.config.maketempdir(pyfuncitem.name)
|
||||
self._old = self.tmpdir.chdir()
|
||||
pyfuncitem.addfinalizer(self.finalize)
|
||||
|
||||
def run(self):
|
||||
return py.process.cmdexec("echo hello")
|
||||
|
||||
def finalize(self):
|
||||
self._old.chdir()
|
||||
# cleanup any other resources
|
||||
|
||||
and the actual test function example:
|
||||
|
||||
def test_some_acceptance_aspect(accept):
|
||||
accept.tmpdir.mkdir("somesub")
|
||||
result = accept.run()
|
||||
assert result
|
||||
|
||||
for registering funcargs from a plugin, talk to the
|
||||
test configuration object like this::
|
||||
|
||||
XXX
|
||||
|
||||
|
Loading…
Reference in New Issue