Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc(plugin_hooks): Improve documentation for writing plugin hooks. #5517

Merged
merged 2 commits into from Jun 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/5517.doc.rst
@@ -0,0 +1 @@
Improve "Declaring new hooks" section in chapter "Writing Plugins"
52 changes: 50 additions & 2 deletions doc/en/writing_plugins.rst
Expand Up @@ -621,12 +621,60 @@ the new plugin:

Hooks are usually declared as do-nothing functions that contain only
documentation describing when the hook will be called and what return values
are expected.
are expected. The names of the functions must start with `pytest_` otherwise pytest won't recognize them.

For an example, see `newhooks.py`_ from `xdist <https://github.com/pytest-dev/pytest-xdist>`_.
Here's an example. Let's assume this code is in the ``hooks.py`` module.

.. code-block:: python

def pytest_my_hook(config):
"""
Receives the pytest config and does things with it
"""

To register the hooks with pytest they need to be structured in their own module or class. This
class or module can then be passed to the ``pluginmanager`` using the ``pytest_addhooks`` function
(which itself is a hook exposed by pytest).

.. code-block:: python

def pytest_addhooks(pluginmanager):
""" This example assumes the hooks are grouped in the 'hooks' module. """
from my_app.tests import hooks
pluginmanager.add_hookspecs(hooks)

For a real world example, see `newhooks.py`_ from `xdist <https://github.com/pytest-dev/pytest-xdist>`_.

.. _`newhooks.py`: https://github.com/pytest-dev/pytest-xdist/blob/974bd566c599dc6a9ea291838c6f226197208b46/xdist/newhooks.py

Hooks may be called both from fixtures or from other hooks. In both cases, hooks are called
through the ``hook`` object, available in the ``config`` object. Most hooks receive a
``config`` object directly, while fixtures may use the ``pytestconfig`` fixture which provides the same object.

.. code-block:: python

@pytest.fixture()
def my_fixture(pytestconfig):
# call the hook called "pytest_my_hook"
# `result` will be a list of return values from all registered functions.
result = pytestconfig.hook.pytest_my_hook(config=pytestconfig)

.. note::
Hooks receive parameters using only keyword arguments.

Now your hook is ready to be used. To register a function at the hook, other plugins or users must
now simply define the function ``pytest_my_hook`` with the correct signature in their ``conftest.py``.

Example:

.. code-block:: python

def pytest_my_hook(config):
"""
Print all active hooks to the screen.
"""
print(config.hook)


Optionally using hooks from 3rd party plugins
---------------------------------------------
Expand Down