fix issue127 improve pytest_addoption docs, add new config.getoption(name) method for consistency.

This commit is contained in:
holger krekel 2012-11-06 14:09:12 +01:00
parent dba2a8bc64
commit 33cd414420
10 changed files with 73 additions and 18 deletions

View File

@ -27,6 +27,9 @@ Changes between 2.3.2 and 2.3.3.dev
- fix issue217 - support mock.patch with pytest's fixtures - note that
you need either mock-1.0.1 or the python3.3 builtin unittest.mock.
- fix issue127 - improve documentation for pytest_addoption() and
add a ``config.getoption(name)`` helper function for consistency.
Changes between 2.3.1 and 2.3.2
-----------------------------------

View File

@ -1,2 +1,2 @@
#
__version__ = '2.3.3.dev4'
__version__ = '2.3.3.dev5'

View File

@ -271,9 +271,8 @@ class CmdOptions(object):
class Config(object):
""" access to configuration values, pluginmanager and plugin hooks. """
def __init__(self, pluginmanager=None):
#: command line option values, which must have been previously added
#: via calls like ``parser.addoption(...)`` or
#: ``parser.getgroup(groupname).addoption(...)``
#: access to command line option as attributes.
#: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
self.option = CmdOptions()
self._parser = Parser(
usage="usage: %prog [options] [file_or_dir] [file_or_dir] [...]",
@ -285,6 +284,7 @@ class Config(object):
self._conftest = Conftest(onimport=self._onimportconftest)
self.hook = self.pluginmanager.hook
self._inicache = {}
self._opt2dest = {}
self._cleanup = []
@classmethod
@ -305,6 +305,9 @@ class Config(object):
self.pluginmanager.consider_conftest(conftestmodule)
def _processopt(self, opt):
for name in opt._short_opts + opt._long_opts:
self._opt2dest[name] = opt.dest
if hasattr(opt, 'default') and opt.dest:
if not hasattr(self.option, opt.dest):
setattr(self.option, opt.dest, opt.default)
@ -383,8 +386,9 @@ class Config(object):
x.append(line) # modifies the cached list inline
def getini(self, name):
""" return configuration value from an ini file. If the
specified name hasn't been registered through a prior ``parse.addini``
""" return configuration value from an :ref:`ini file <inifiles>`. If the
specified name hasn't been registered through a prior
:py:func:`parser.addini <pytest.config.Parser.addini>`
call (usually from a plugin), a ValueError is raised. """
try:
return self._inicache[name]
@ -438,8 +442,22 @@ class Config(object):
self._checkconftest(name)
return self._conftest.rget(name, path)
def getoption(self, name):
""" return command line option value.
:arg name: name of the option. You may also specify
the literal ``--OPT`` option instead of the "dest" option name.
"""
name = self._opt2dest.get(name, name)
try:
return getattr(self.option, name)
except AttributeError:
raise ValueError("no option named %r" % (name,))
def getvalue(self, name, path=None):
""" return ``name`` value looked set from command line options.
""" return command line option value.
:arg name: name of the command line option
(deprecated) if we can't find the option also lookup
the name in a matching conftest file.

View File

@ -23,10 +23,28 @@ def pytest_cmdline_preparse(config, args):
"""modify command line arguments before option parsing. """
def pytest_addoption(parser):
"""use the parser to add optparse-style options and ini-style
config values via calls, see :py:func:`parser.addoption(...)
<_pytest.config.Parser.addoption>`
and :py:func:`parser.addini(...) <_pytest.config.Parser.addini>`.
"""register optparse-style options and ini-style config values.
This function must be implemented in a :ref:`plugin <pluginorder>` and is
called once at the beginning of a test run.
:arg parser: To add command line options, call
:py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`.
To add ini-file values call :py:func:`parser.addini(...)
<_pytest.config.Parser.addini>`.
Options can later be accessed through the
:py:class:`config <_pytest.config.Config>` object, respectively:
- :py:func:`config.getoption(name) <_pytest.config.Config.getoption>` to
retrieve the value of a command line option.
- :py:func:`config.getini(name) <_pytest.config.Config.getini>` to retrieve
a value read from an ini-style file.
The config object is passed around on many internal objects via the ``.config``
attribute or can be retrieved as the ``pytestconfig`` fixture or accessed
via (deprecated) ``pytest.config``.
"""
def pytest_cmdline_main(config):
@ -35,7 +53,7 @@ def pytest_cmdline_main(config):
pytest_cmdline_main.firstresult = True
def pytest_configure(config):
""" called after command line options have been parsed.
""" called after command line options have been parsed
and all plugins and initial conftest files been loaded.
"""

View File

@ -12,6 +12,8 @@ configurations files by using the general help option::
This will display command line and configuration file settings
which were registered by installed plugins.
.. _inifiles:
How test configuration is read from configuration INI-files
-------------------------------------------------------------

View File

@ -194,7 +194,7 @@ specifies via named environments::
import pytest
def pytest_addoption(parser):
parser.addoption("-E", dest="env", action="store", metavar="NAME",
parser.addoption("-E", action="store", metavar="NAME",
help="only run tests matching the environment NAME.")
def pytest_configure(config):
@ -206,7 +206,7 @@ specifies via named environments::
envmarker = item.keywords.get("env", None)
if envmarker is not None:
envname = envmarker.args[0]
if envname != item.config.option.env:
if envname != item.config.getoption("-E"):
pytest.skip("test requires env %r" % envname)
A test file using this local plugin::

View File

@ -33,7 +33,7 @@ provide the ``cmdopt`` through a :ref:`fixture function <fixture function>`::
@pytest.fixture
def cmdopt(request):
return request.config.option.cmdopt
return request.config.getoption("--cmdopt")
Let's run this without supplying our new option::
@ -129,7 +129,7 @@ line option to control skipping of ``slow`` marked tests::
help="run slow tests")
def pytest_runtest_setup(item):
if 'slow' in item.keywords and not item.config.getvalue("runslow"):
if 'slow' in item.keywords and not item.config.getoption("--runslow"):
pytest.skip("need --runslow option to run")
We can now write a test module like this::

View File

@ -5,7 +5,7 @@ Working with plugins and conftest files
py.test implements all aspects of configuration, collection, running and reporting by calling `well specified hooks`_. Virtually any Python module can be registered as a plugin. It can implement any number of hook functions (usually two or three) which all have a ``pytest_`` prefix, making hook functions easy to distinguish and find. There are three basic location types:
* `builtin plugins`_: loaded from py.test's own ``pytest/plugin`` directory.
* `builtin plugins`_: loaded from py.test's internal ``_pytest`` directory.
* `external plugins`_: modules discovered through `setuptools entry points`_
* `conftest.py plugins`_: modules auto-discovered in test directories
@ -155,6 +155,8 @@ If a package is installed this way, py.test will load
``myproject.pluginmodule`` as a plugin which can define
`well specified hooks`_.
.. _`pluginorder`:
Plugin discovery order at tool startup
--------------------------------------------
@ -175,6 +177,7 @@ py.test loads plugin modules at tool startup in the following way:
* by recursively loading all plugins specified by the
``pytest_plugins`` variable in ``conftest.py`` files
Requiring/Loading plugins in a test module or conftest file
-------------------------------------------------------------

View File

@ -24,7 +24,7 @@ def main():
name='pytest',
description='py.test: simple powerful testing with Python',
long_description = long_description,
version='2.3.3.dev4',
version='2.3.3.dev5',
url='http://pytest.org',
license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

View File

@ -103,6 +103,16 @@ class TestConfigAPI:
assert config.getvalue("x", o) == 1
pytest.raises(KeyError, 'config.getvalue("y", o)')
def test_config_getoption(self, testdir):
testdir.makeconftest("""
def pytest_addoption(parser):
parser.addoption("--hello", "-X", dest="hello")
""")
config = testdir.parseconfig("--hello=this")
for x in ("hello", "--hello", "-X"):
assert config.getoption(x) == "this"
pytest.raises(ValueError, "config.getoption('qweqwe')")
def test_config_getvalueorskip(self, testdir):
config = testdir.parseconfig()
pytest.raises(pytest.skip.Exception,
@ -304,3 +314,4 @@ def test_cmdline_processargs_simple(testdir):
"*pytest*",
"*-h*",
])