2011-03-04 06:40:38 +08:00
.. _plugins:
2010-12-06 23:54:42 +08:00
Working with plugins and conftest files
2010-11-02 07:53:53 +08:00
=============================================
2014-01-18 19:31:33 +08:00
``pytest`` 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:
2010-11-02 07:53:53 +08:00
2014-01-18 19:31:33 +08:00
* `builtin plugins`_: loaded from pytest's internal ``_pytest`` directory.
2010-11-02 07:53:53 +08:00
* `external plugins`_: modules discovered through `setuptools entry points`_
* `conftest.py plugins`_: modules auto-discovered in test directories
.. _`pytest/plugin`: http://bitbucket.org/hpk42/pytest/src/tip/pytest/plugin/
.. _`conftest.py plugins`:
2010-12-06 23:54:42 +08:00
.. _`conftest.py`:
2011-03-04 06:40:38 +08:00
.. _`localplugin`:
.. _`conftest`:
2010-11-02 07:53:53 +08:00
conftest.py: local per-directory plugins
--------------------------------------------------------------
local ``conftest.py`` plugins contain directory-specific hook
2010-11-07 17:19:58 +08:00
implementations. Session and test running activities will
2011-03-04 06:40:38 +08:00
invoke all hooks defined in ``conftest.py`` files closer to the
root of the filesystem. Example: Assume the following layout
and content of files::
2010-11-02 07:53:53 +08:00
a/conftest.py:
def pytest_runtest_setup(item):
# called for running each test in 'a' directory
print ("setting up", item)
a/test_in_subdir.py:
def test_sub():
pass
test_flat.py:
def test_flat():
pass
Here is how you might run it::
py.test test_flat.py # will not show "setting up"
py.test a/test_sub.py # will show "setting up"
.. Note::
If you have ``conftest.py`` files which do not reside in a
python package directory (i.e. one containing an ``__init__.py``) then
2011-02-17 21:46:40 +08:00
"import conftest" can be ambiguous because there might be other
2010-11-02 07:53:53 +08:00
``conftest.py`` files as well on your PYTHONPATH or ``sys.path``.
2010-11-06 18:38:53 +08:00
It is thus good practise for projects to either put ``conftest.py``
under a package scope or to never import anything from a
2010-11-02 07:53:53 +08:00
conftest.py file.
.. _`external plugins`:
2010-12-06 23:54:42 +08:00
.. _`extplugins`:
2010-11-02 07:53:53 +08:00
2010-11-06 06:37:25 +08:00
Installing External Plugins / Searching
2010-11-02 07:53:53 +08:00
------------------------------------------------------
Installing a plugin happens through any usual Python installation
tool, for example::
pip install pytest-NAME
pip uninstall pytest-NAME
2014-01-18 19:31:33 +08:00
If a plugin is installed, ``pytest`` automatically finds and integrates it,
2014-02-19 08:33:13 +08:00
there is no need to activate it. We have a :doc:`page listing
all 3rd party plugins and their status against the latest py.test version
<plugins_index/index>` and here is a little annotated list
for some popular plugins:
2012-10-09 20:35:17 +08:00
.. _`django`: https://www.djangoproject.com/
2012-10-18 18:24:50 +08:00
* `pytest-django <http://pypi.python.org/pypi/pytest-django>`_: write tests
2012-10-09 20:35:17 +08:00
for `django`_ apps, using pytest integration.
2010-12-06 23:54:42 +08:00
2012-10-22 15:32:41 +08:00
* `pytest-twisted <http://pypi.python.org/pypi/pytest-twisted>`_: write tests
for `twisted <http://twistedmatrix.com>`_ apps, starting a reactor and
processing deferreds from test functions.
2010-12-06 23:54:42 +08:00
* `pytest-capturelog <http://pypi.python.org/pypi/pytest-capturelog>`_:
to capture and assert about messages from the logging module
2013-05-08 03:34:59 +08:00
* `pytest-cov <http://pypi.python.org/pypi/pytest-cov>`_:
coverage reporting, compatible with distributed testing
2010-12-06 23:54:42 +08:00
* `pytest-xdist <http://pypi.python.org/pypi/pytest-xdist>`_:
2012-10-09 20:35:17 +08:00
to distribute tests to CPUs and remote hosts, to run in boxed
mode which allows to survive segmentation faults, to run in
2014-01-18 19:31:33 +08:00
looponfailing mode, automatically re-running failing tests
2012-10-09 20:35:17 +08:00
on file changes, see also :ref:`xdist`
2013-05-08 03:34:59 +08:00
* `pytest-instafail <http://pypi.python.org/pypi/pytest-instafail>`_:
to report failures while the test run is happening.
* `pytest-bdd <http://pypi.python.org/pypi/pytest-bdd>`_ and
2014-01-18 19:31:33 +08:00
`pytest-konira <http://pypi.python.org/pypi/pytest-konira>`_
2013-05-08 03:34:59 +08:00
to write tests using behaviour-driven testing.
2012-10-09 20:35:17 +08:00
* `pytest-timeout <http://pypi.python.org/pypi/pytest-timeout>`_:
to timeout tests based on function marks or global definitions.
* `pytest-cache <http://pypi.python.org/pypi/pytest-cache>`_:
to interactively re-run failing tests and help other plugins to
store test run information across invocations.
2010-12-06 23:54:42 +08:00
* `pytest-pep8 <http://pypi.python.org/pypi/pytest-pep8>`_:
2011-02-17 21:46:40 +08:00
a ``--pep8`` option to enable PEP8 compliance checking.
2010-12-06 23:54:42 +08:00
* `oejskit <http://pypi.python.org/pypi/oejskit>`_:
a plugin to run javascript unittests in life browsers
2014-02-19 08:33:13 +08:00
To see a complete list of all plugins with their latest testing
status against different py.test and Python versions, please visit
`pytest-plugs <http://pytest-plugs.herokuapp.com/>`_.
You may also discover more plugins through a `pytest- pypi.python.org search`_.
2010-11-02 07:53:53 +08:00
.. _`available installable plugins`:
.. _`pytest- pypi.python.org search`: http://pypi.python.org/pypi?%3Aaction=search&term=pytest-&submit=search
2010-11-06 06:37:25 +08:00
Writing a plugin by looking at examples
2010-11-02 07:53:53 +08:00
------------------------------------------------------
.. _`Distribute`: http://pypi.python.org/pypi/distribute
.. _`setuptools`: http://pypi.python.org/pypi/setuptools
If you want to write a plugin, there are many real-life examples
you can copy from:
2010-11-06 06:37:25 +08:00
* a custom collection example plugin: :ref:`yaml plugin`
2014-01-18 19:31:33 +08:00
* around 20 `builtin plugins`_ which provide pytest's own functionality
2012-10-09 20:35:17 +08:00
* many `external plugins`_ providing additional features
2010-11-02 07:53:53 +08:00
2010-11-18 21:56:16 +08:00
All of these plugins implement the documented `well specified hooks`_
to extend and add functionality.
2010-11-06 06:37:25 +08:00
.. _`setuptools entry points`:
Making your plugin installable by others
-----------------------------------------------
2010-11-02 07:53:53 +08:00
If you want to make your plugin externally available, you
2011-03-04 06:40:38 +08:00
may define a so-called entry point for your distribution so
2014-01-18 19:31:33 +08:00
that ``pytest`` finds your plugin module. Entry points are
2010-11-02 07:53:53 +08:00
a feature that is provided by `setuptools`_ or `Distribute`_.
2014-01-18 19:31:33 +08:00
pytest looks up the ``pytest11`` entrypoint to discover its
2014-01-19 17:26:55 +08:00
plugins and you can thus make your plugin available by defining
2011-03-04 06:40:38 +08:00
it in your setuptools/distribute-based setup-invocation:
2010-11-02 07:53:53 +08:00
.. sourcecode:: python
# sample ./setup.py file
from setuptools import setup
setup(
name="myproject",
packages = ['myproject']
2014-01-18 19:31:33 +08:00
# the following makes a plugin available to pytest
2010-11-02 07:53:53 +08:00
entry_points = {
'pytest11': [
'name_of_plugin = myproject.pluginmodule',
]
},
)
2014-01-18 19:31:33 +08:00
If a package is installed this way, ``pytest`` will load
2011-03-04 06:40:38 +08:00
``myproject.pluginmodule`` as a plugin which can define
`well specified hooks`_.
2010-11-02 07:53:53 +08:00
2012-11-06 21:09:12 +08:00
.. _`pluginorder`:
2010-11-02 07:53:53 +08:00
Plugin discovery order at tool startup
--------------------------------------------
2014-01-18 19:31:33 +08:00
``pytest`` loads plugin modules at tool startup in the following way:
2010-11-02 07:53:53 +08:00
* by loading all builtin plugins
* by loading all plugins registered through `setuptools entry points`_.
* by pre-scanning the command line for the ``-p name`` option
and loading the specified plugin before actual command line parsing.
* by loading all :file:`conftest.py` files as inferred by the command line
2014-01-23 22:25:01 +08:00
invocation:
- if no test paths are specified use current dir as a test path
- if exists, load ``conftest.py`` and ``test*/conftest.py`` relative
to the directory part of the first test path.
Note that pytest does not find ``conftest.py`` files in deeper nested
sub directories at tool startup. It is usually a good idea to keep
your conftest.py file in the top level test or project root directory.
2010-11-02 07:53:53 +08:00
* by recursively loading all plugins specified by the
``pytest_plugins`` variable in ``conftest.py`` files
2012-11-06 21:09:12 +08:00
2010-11-02 07:53:53 +08:00
Requiring/Loading plugins in a test module or conftest file
-------------------------------------------------------------
You can require plugins in a test module or a conftest file like this::
pytest_plugins = "name1", "name2",
When the test module or conftest plugin is loaded the specified plugins
will be loaded as well. You can also use dotted path like this::
pytest_plugins = "myapp.testsupport.myplugin"
2014-01-18 19:31:33 +08:00
which will import the specified module as a ``pytest`` plugin.
2010-11-02 07:53:53 +08:00
Accessing another plugin by name
--------------------------------------------
If a plugin wants to collaborate with code from
another plugin it can obtain a reference through
the plugin manager like this:
.. sourcecode:: python
plugin = config.pluginmanager.getplugin("name_of_plugin")
If you want to look at the names of existing plugins, use
the ``--traceconfig`` option.
2010-12-06 23:54:42 +08:00
.. _`findpluginname`:
Finding out which plugins are active
----------------------------------------------------------------------------
If you want to find out which plugins are active in your
environment you can type::
py.test --traceconfig
and will get an extended test header which shows activated plugins
and their names. It will also print local plugins aka
:ref:`conftest.py <conftest>` files when they are loaded.
.. _`cmdunregister`:
2011-09-06 17:43:42 +08:00
Deactivating / unregistering a plugin by name
2010-12-06 23:54:42 +08:00
----------------------------------------------------------------------------
You can prevent plugins from loading or unregister them::
py.test -p no:NAME
This means that any subsequent try to activate/load the named
plugin will it already existing. See :ref:`findpluginname` for
how to obtain the name of a plugin.
2010-11-06 18:38:53 +08:00
.. _`builtin plugins`:
2014-01-18 19:31:33 +08:00
pytest default plugin reference
2010-11-06 18:38:53 +08:00
====================================
2010-12-06 23:54:42 +08:00
You can find the source code for the following plugins
in the `pytest repository <http://bitbucket.org/hpk42/pytest/>`_.
2010-11-06 18:38:53 +08:00
.. autosummary::
2010-11-13 18:10:45 +08:00
_pytest.assertion
_pytest.capture
_pytest.config
_pytest.doctest
_pytest.genscript
_pytest.helpconfig
_pytest.junitxml
_pytest.mark
_pytest.monkeypatch
_pytest.nose
_pytest.pastebin
_pytest.pdb
_pytest.pytester
_pytest.python
_pytest.recwarn
_pytest.resultlog
_pytest.runner
2010-12-06 23:54:42 +08:00
_pytest.main
2010-11-13 18:10:45 +08:00
_pytest.skipping
_pytest.terminal
_pytest.tmpdir
_pytest.unittest
2010-11-06 18:38:53 +08:00
2010-11-02 07:53:53 +08:00
.. _`well specified hooks`:
2014-01-18 19:31:33 +08:00
pytest hook reference
2010-11-02 07:53:53 +08:00
====================================
2011-09-06 17:43:42 +08:00
Hook specification and validation
2010-11-02 07:53:53 +08:00
-----------------------------------------
2014-01-18 19:31:33 +08:00
``pytest`` calls hook functions to implement initialization, running,
test execution and reporting. When ``pytest`` loads a plugin it validates
2011-03-04 06:40:38 +08:00
that each hook function conforms to its respective hook specification.
2010-11-02 07:53:53 +08:00
Each hook function name and its argument names need to match a hook
2011-03-04 06:40:38 +08:00
specification. However, a hook function may accept *fewer* parameters
by simply not specifying them. If you mistype argument names or the
hook name itself you get an error showing the available arguments.
2010-11-02 07:53:53 +08:00
2011-12-05 18:10:48 +08:00
Initialization, command line and configuration hooks
2010-11-02 07:53:53 +08:00
--------------------------------------------------------------------
2010-11-13 18:10:45 +08:00
.. currentmodule:: _pytest.hookspec
2010-11-02 07:53:53 +08:00
2014-03-25 21:43:58 +08:00
.. autofunction:: pytest_load_initial_conftests
2010-12-07 19:34:18 +08:00
.. autofunction:: pytest_cmdline_preparse
2010-11-02 07:53:53 +08:00
.. autofunction:: pytest_cmdline_parse
.. autofunction:: pytest_namespace
.. autofunction:: pytest_addoption
.. autofunction:: pytest_cmdline_main
.. autofunction:: pytest_configure
.. autofunction:: pytest_unconfigure
2011-09-06 17:43:42 +08:00
Generic "runtest" hooks
2010-11-02 07:53:53 +08:00
------------------------------
2014-03-03 05:52:38 +08:00
All runtest related hooks receive a :py:class:`pytest.Item` object.
2010-11-02 07:53:53 +08:00
.. autofunction:: pytest_runtest_protocol
.. autofunction:: pytest_runtest_setup
.. autofunction:: pytest_runtest_call
.. autofunction:: pytest_runtest_teardown
.. autofunction:: pytest_runtest_makereport
For deeper understanding you may look at the default implementation of
2010-11-13 18:10:45 +08:00
these hooks in :py:mod:`_pytest.runner` and maybe also
2011-03-04 06:40:38 +08:00
in :py:mod:`_pytest.pdb` which interacts with :py:mod:`_pytest.capture`
and its input/output capturing in order to immediately drop
into interactive debugging when a test failure occurs.
2010-11-02 07:53:53 +08:00
2010-11-13 18:10:45 +08:00
The :py:mod:`_pytest.terminal` reported specifically uses
2010-11-02 07:53:53 +08:00
the reporting hook to print information about a test run.
2012-07-16 17:11:26 +08:00
2011-09-06 17:43:42 +08:00
Collection hooks
2010-11-02 07:53:53 +08:00
------------------------------
2014-01-18 19:31:33 +08:00
``pytest`` calls the following hooks for collecting files and directories:
2010-11-02 07:53:53 +08:00
.. autofunction:: pytest_ignore_collect
.. autofunction:: pytest_collect_directory
.. autofunction:: pytest_collect_file
For influencing the collection of objects in Python modules
you can use the following hook:
.. autofunction:: pytest_pycollect_makeitem
2012-07-16 17:11:26 +08:00
.. autofunction:: pytest_generate_tests
2010-11-02 07:53:53 +08:00
2013-08-09 05:32:14 +08:00
After collection is complete, you can modify the order of
items, delete or otherwise amend the test items:
.. autofunction:: pytest_collection_modifyitems
2010-11-02 07:53:53 +08:00
2011-09-06 17:43:42 +08:00
Reporting hooks
2010-11-02 07:53:53 +08:00
------------------------------
2010-11-07 17:19:58 +08:00
Session related reporting hooks:
2010-11-02 07:53:53 +08:00
2013-06-03 16:04:50 +08:00
.. autofunction:: pytest_collectstart
.. autofunction:: pytest_itemcollected
.. autofunction:: pytest_collectreport
.. autofunction:: pytest_deselected
2010-11-02 07:53:53 +08:00
And here is the central hook for reporting about
test execution:
2013-06-03 16:04:50 +08:00
.. autofunction:: pytest_runtest_logreport
2010-11-02 07:53:53 +08:00
2013-09-06 17:56:04 +08:00
Debugging/Interaction hooks
--------------------------------------
There are few hooks which can be used for special
reporting or interaction with exceptions:
.. autofunction:: pytest_internalerror
.. autofunction:: pytest_keyboard_interrupt
.. autofunction:: pytest_exception_interact
2012-06-25 23:35:33 +08:00
Reference of objects involved in hooks
2010-11-02 07:53:53 +08:00
===========================================================
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.config.Config()
2010-11-02 07:53:53 +08:00
:members:
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.config.Parser()
2010-11-02 07:53:53 +08:00
:members:
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.main.Node()
2010-11-02 07:53:53 +08:00
:members:
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.main.Collector()
:members:
:show-inheritance:
2010-11-02 07:53:53 +08:00
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.main.Item()
:members:
:show-inheritance:
2010-11-02 07:53:53 +08:00
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.python.Module()
:members:
:show-inheritance:
2010-11-02 07:53:53 +08:00
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.python.Class()
:members:
:show-inheritance:
2010-11-02 07:53:53 +08:00
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.python.Function()
:members:
:show-inheritance:
2010-11-02 07:53:53 +08:00
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.runner.CallInfo()
2010-11-02 07:53:53 +08:00
:members:
2012-06-25 23:35:33 +08:00
.. autoclass:: _pytest.runner.TestReport()
2010-11-02 07:53:53 +08:00
:members: