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
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser, pluginmanager):
|
||||||
parser.addoption(
|
parser.addoption(
|
||||||
"-E",
|
"-E",
|
||||||
action="store",
|
action="store",
|
||||||
|
|
|
@ -36,7 +36,7 @@ Now we add a test configuration like this:
|
||||||
# content of conftest.py
|
# content of conftest.py
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser, pluginmanager):
|
||||||
parser.addoption("--all", action="store_true", help="run all combinations")
|
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
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser, pluginmanager):
|
||||||
parser.addoption(
|
parser.addoption(
|
||||||
"--cmdopt", action="store", default="type1", help="my option: type1 or type2"
|
"--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
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser, pluginmanager):
|
||||||
parser.addoption(
|
parser.addoption(
|
||||||
"--runslow", action="store_true", default=False, help="run slow tests"
|
"--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
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser, pluginmanager):
|
||||||
group = parser.getgroup("helloworld")
|
group = parser.getgroup("helloworld")
|
||||||
group.addoption(
|
group.addoption(
|
||||||
"--name",
|
"--name",
|
||||||
|
@ -677,6 +677,56 @@ Example:
|
||||||
print(config.hook)
|
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
|
Optionally using hooks from 3rd party plugins
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -697,7 +697,9 @@ class Config:
|
||||||
self._cleanup = [] # type: List[Callable[[], None]]
|
self._cleanup = [] # type: List[Callable[[], None]]
|
||||||
self.pluginmanager.register(self, "pytestconfig")
|
self.pluginmanager.register(self, "pytestconfig")
|
||||||
self._configured = False
|
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
|
@property
|
||||||
def invocation_dir(self):
|
def invocation_dir(self):
|
||||||
|
|
|
@ -35,7 +35,7 @@ def pytest_plugin_registered(plugin, manager):
|
||||||
|
|
||||||
|
|
||||||
@hookspec(historic=True)
|
@hookspec(historic=True)
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser, pluginmanager):
|
||||||
"""register argparse-style options and ini-style config values,
|
"""register argparse-style options and ini-style config values,
|
||||||
called once at the beginning of a test run.
|
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(...)
|
To add ini-file values call :py:func:`parser.addini(...)
|
||||||
<_pytest.config.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
|
Options can later be accessed through the
|
||||||
:py:class:`config <_pytest.config.Config>` object, respectively:
|
:py:class:`config <_pytest.config.Config>` object, respectively:
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,36 @@ class TestPytestPluginInteractions:
|
||||||
ihook_b = session.gethookproxy(testdir.tmpdir.join("tests"))
|
ihook_b = session.gethookproxy(testdir.tmpdir.join("tests"))
|
||||||
assert ihook_a is not ihook_b
|
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):
|
def test_default_markers(testdir):
|
||||||
result = testdir.runpytest("--markers")
|
result = testdir.runpytest("--markers")
|
||||||
|
|
Loading…
Reference in New Issue