Making it possible to access the pluginmanager in the pytest_addoption hook
This commit is contained in:
parent
cefe6bfec3
commit
7a96d94fd4
|
@ -0,0 +1,5 @@
|
|||
Adding the pluginmanager as an option to :py:func:`~hookspec.pytest_addoption`
|
||||
so that hooks can be invoked when setting up command line options. This is
|
||||
useful for having one plugin communicate things to another plugin,
|
||||
such as default values or which set of command line options to add. See
|
||||
:ref:`Using hooks in pytest_addoption <addoptionhooks>` for more details.
|
|
@ -364,7 +364,7 @@ specifies via named environments:
|
|||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
parser.addoption(
|
||||
"-E",
|
||||
action="store",
|
||||
|
|
|
@ -36,7 +36,7 @@ Now we add a test configuration like this:
|
|||
# content of conftest.py
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
parser.addoption("--all", action="store_true", help="run all combinations")
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ provide the ``cmdopt`` through a :ref:`fixture function <fixture function>`:
|
|||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
parser.addoption(
|
||||
"--cmdopt", action="store", default="type1", help="my option: type1 or type2"
|
||||
)
|
||||
|
@ -151,7 +151,7 @@ line option to control skipping of ``pytest.mark.slow`` marked tests:
|
|||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
parser.addoption(
|
||||
"--runslow", action="store_true", default=False, help="run slow tests"
|
||||
)
|
||||
|
|
|
@ -338,7 +338,7 @@ string value of ``Hello World!`` if we do not supply a value or ``Hello
|
|||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
group = parser.getgroup("helloworld")
|
||||
group.addoption(
|
||||
"--name",
|
||||
|
@ -677,6 +677,56 @@ Example:
|
|||
print(config.hook)
|
||||
|
||||
|
||||
.. _`addoptionhooks`:
|
||||
|
||||
|
||||
Using hooks in pytest_addoption
|
||||
-------------------------------
|
||||
|
||||
Occasionally, it is necessary to change the way in which command line options
|
||||
are defined by one plugin based on hooks in another plugin. For example,
|
||||
a plugin may expose a command line option for which another plugin needs
|
||||
to define the default value. The pluginmanager can be used to install and
|
||||
use hooks to accomplish this. The plugin would define and add the hooks
|
||||
and use pytest_addoption as follows:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# contents of hooks.py
|
||||
|
||||
# Use firstresult=True because we only want one plugin to define this
|
||||
# default value
|
||||
@hookspec(firstresult=True)
|
||||
def pytest_config_file_default_value():
|
||||
""" Return the default value for the config file command line option. """
|
||||
|
||||
|
||||
# contents of myplugin.py
|
||||
|
||||
|
||||
def pytest_addhooks(pluginmanager):
|
||||
""" This example assumes the hooks are grouped in the 'hooks' module. """
|
||||
from . import hook
|
||||
|
||||
pluginmanager.add_hookspecs(hook)
|
||||
|
||||
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
default_value = pluginmanager.hook.pytest_config_file_default_value()
|
||||
parser.addoption(
|
||||
"--config-file",
|
||||
help="Config file to use, defaults to %(default)s",
|
||||
default=default_value,
|
||||
)
|
||||
|
||||
The conftest.py that is using myplugin would simply define the hook as follows:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def pytest_config_file_default_value():
|
||||
return "config.yaml"
|
||||
|
||||
|
||||
Optionally using hooks from 3rd party plugins
|
||||
---------------------------------------------
|
||||
|
||||
|
|
|
@ -697,7 +697,9 @@ class Config:
|
|||
self._cleanup = [] # type: List[Callable[[], None]]
|
||||
self.pluginmanager.register(self, "pytestconfig")
|
||||
self._configured = False
|
||||
self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))
|
||||
self.hook.pytest_addoption.call_historic(
|
||||
kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager)
|
||||
)
|
||||
|
||||
@property
|
||||
def invocation_dir(self):
|
||||
|
|
|
@ -35,7 +35,7 @@ def pytest_plugin_registered(plugin, manager):
|
|||
|
||||
|
||||
@hookspec(historic=True)
|
||||
def pytest_addoption(parser):
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
"""register argparse-style options and ini-style config values,
|
||||
called once at the beginning of a test run.
|
||||
|
||||
|
@ -50,6 +50,11 @@ def pytest_addoption(parser):
|
|||
To add ini-file values call :py:func:`parser.addini(...)
|
||||
<_pytest.config.Parser.addini>`.
|
||||
|
||||
:arg _pytest.config.PytestPluginManager pluginmanager: pytest plugin manager,
|
||||
which can be used to install :py:func:`hookspec`'s or :py:func:`hookimpl`'s
|
||||
and allow one plugin to call another plugin's hooks to change how
|
||||
command line options are added.
|
||||
|
||||
Options can later be accessed through the
|
||||
:py:class:`config <_pytest.config.Config>` object, respectively:
|
||||
|
||||
|
|
|
@ -135,6 +135,36 @@ class TestPytestPluginInteractions:
|
|||
ihook_b = session.gethookproxy(testdir.tmpdir.join("tests"))
|
||||
assert ihook_a is not ihook_b
|
||||
|
||||
def test_hook_with_addoption(self, testdir):
|
||||
"""Test that hooks can be used in a call to pytest_addoption"""
|
||||
testdir.makepyfile(
|
||||
newhooks="""
|
||||
import pytest
|
||||
@pytest.hookspec(firstresult=True)
|
||||
def pytest_default_value():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
testdir.makepyfile(
|
||||
myplugin="""
|
||||
import newhooks
|
||||
def pytest_addhooks(pluginmanager):
|
||||
pluginmanager.add_hookspecs(newhooks)
|
||||
def pytest_addoption(parser, pluginmanager):
|
||||
default_value = pluginmanager.hook.pytest_default_value()
|
||||
parser.addoption("--config", help="Config, defaults to %(default)s", default=default_value)
|
||||
"""
|
||||
)
|
||||
testdir.makeconftest(
|
||||
"""
|
||||
pytest_plugins=("myplugin",)
|
||||
def pytest_default_value():
|
||||
return "default_value"
|
||||
"""
|
||||
)
|
||||
res = testdir.runpytest("--help")
|
||||
res.stdout.fnmatch_lines(["*--config=CONFIG*default_value*"])
|
||||
|
||||
|
||||
def test_default_markers(testdir):
|
||||
result = testdir.runpytest("--markers")
|
||||
|
|
Loading…
Reference in New Issue