2009-06-11 20:48:42 +08:00
|
|
|
================================================
|
2010-07-27 03:15:15 +08:00
|
|
|
Customizing and Extending py.test
|
2009-06-11 20:48:42 +08:00
|
|
|
================================================
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
basic test configuration
|
2009-08-19 01:04:57 +08:00
|
|
|
===================================
|
|
|
|
|
2010-10-12 16:59:04 +08:00
|
|
|
Command line options
|
2009-08-19 01:04:57 +08:00
|
|
|
---------------------------------
|
|
|
|
|
|
|
|
You can see command line options by running::
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
py.test -h
|
2009-08-19 01:04:57 +08:00
|
|
|
|
|
|
|
This will display all available command line options
|
2010-07-27 03:15:15 +08:00
|
|
|
in your specific environment.
|
2009-08-19 01:04:57 +08:00
|
|
|
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
setting persistent option defaults
|
2009-08-19 21:45:01 +08:00
|
|
|
------------------------------------
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
py.test will lookup option values in this order:
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2009-08-19 21:45:01 +08:00
|
|
|
* command line
|
2010-07-27 03:15:15 +08:00
|
|
|
* conftest.py files
|
2009-08-19 21:45:01 +08:00
|
|
|
* environment variables
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
To get an overview on existing names and settings type::
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2009-08-19 21:45:01 +08:00
|
|
|
py.test --help-config
|
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
This will print information about all available options
|
|
|
|
in your environment, including your local plugins and
|
|
|
|
command line options.
|
2009-08-19 01:04:57 +08:00
|
|
|
|
|
|
|
.. _`function arguments`: funcargs.html
|
2010-07-27 03:15:15 +08:00
|
|
|
.. _`extensions`:
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
Plugin basics and project configuration
|
2010-05-02 21:24:02 +08:00
|
|
|
=============================================
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2009-06-11 20:48:42 +08:00
|
|
|
.. _`local plugin`:
|
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
py.test implements all aspects of its functionality by calling `well specified
|
|
|
|
hooks`_. Hook functions are discovered in :file:`conftest.py` files or in
|
|
|
|
`named plugins`_. :file:`conftest.py` files are useful for keeping test
|
|
|
|
extensions and customizations close to test code.
|
|
|
|
|
|
|
|
local conftest.py plugins
|
2009-08-19 01:04:57 +08:00
|
|
|
--------------------------------------------------------------
|
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
local `conftest.py` plugins are usually automatically loaded and
|
|
|
|
registered but its contained hooks are only called when collecting or
|
|
|
|
running tests in files or directories next to or below the ``conftest.py``
|
|
|
|
file. Assume the following layout and content of files::
|
2009-07-15 03:17:13 +08:00
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
a/conftest.py:
|
|
|
|
def pytest_runtest_setup(item):
|
|
|
|
print ("setting up", item)
|
|
|
|
|
|
|
|
a/test_in_subdir.py:
|
|
|
|
def test_sub():
|
|
|
|
pass
|
|
|
|
|
|
|
|
test_flat.py:
|
|
|
|
def test_flat():
|
|
|
|
pass
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
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"
|
|
|
|
|
|
|
|
``py.test`` loads all ``conftest.py`` files upwards from the command
|
|
|
|
line file arguments. It usually looks up configuration values or hooks
|
|
|
|
right-to-left, i.e. the closer conftest files are checked before
|
|
|
|
the further away ones. This means you can have a ``conftest.py``
|
|
|
|
in your home directory to provide global configuration values.
|
|
|
|
|
|
|
|
.. Note::
|
|
|
|
if you have ``conftest.py`` files which do not reside in a
|
2010-10-22 16:09:26 +08:00
|
|
|
python package directory (i.e. one containing an ``__init__.py``) then
|
|
|
|
"import conftest" will be ambigous and should be avoided. If you
|
|
|
|
ever want to import anything from a ``conftest.py`` file
|
|
|
|
put it inside a package. You avoid trouble this way.
|
2010-10-14 00:45:07 +08:00
|
|
|
|
|
|
|
.. _`named plugins`: plugin/index.html
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2009-06-15 23:28:55 +08:00
|
|
|
Plugin discovery at tool startup
|
|
|
|
--------------------------------------------
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2009-06-15 23:28:55 +08:00
|
|
|
py.test loads plugin modules at tool startup in the following way:
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
* by loading all plugins registered through `setuptools entry points`_.
|
2009-11-24 00:20:36 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
* by reading the ``PYTEST_PLUGINS`` environment variable
|
|
|
|
and importing the comma-separated list of named plugins.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
|
|
|
* by pre-scanning the command line for the ``-p name`` option
|
2010-07-27 03:15:15 +08:00
|
|
|
and loading the specified plugin before actual command line parsing.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
* by loading all :file:`conftest.py` files as inferred by the command line
|
|
|
|
invocation (test files and all of its *parent* directories).
|
|
|
|
Note that ``conftest.py`` files from *sub* directories are by default
|
|
|
|
not loaded at tool startup.
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
* by recursively loading all plugins specified by the
|
|
|
|
``pytest_plugins`` variable in a ``conftest.py`` file
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-12 21:34:32 +08:00
|
|
|
Requiring/Loading plugins in a test module or plugin
|
|
|
|
-------------------------------------------------------------
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-10-12 21:34:32 +08:00
|
|
|
You can specify plugins in a test module or a plugin like this::
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
pytest_plugins = "name1", "name2",
|
2009-06-15 23:28:55 +08:00
|
|
|
|
|
|
|
When the test module or plugin is loaded the specified plugins
|
|
|
|
will be loaded. If you specify plugins without the ``pytest_``
|
2010-07-27 03:15:15 +08:00
|
|
|
prefix it will be automatically added. All plugin names
|
|
|
|
must be lowercase.
|
2009-06-15 23:28:55 +08:00
|
|
|
|
|
|
|
.. _`conftest.py plugin`:
|
|
|
|
.. _`conftestplugin`:
|
|
|
|
|
2009-11-24 00:20:36 +08:00
|
|
|
Writing per-project plugins (conftest.py)
|
|
|
|
------------------------------------------------------
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
The purpose of :file:`conftest.py` files is to allow project-specific
|
|
|
|
test customization. They thus make for a good place to implement
|
2010-07-27 03:15:15 +08:00
|
|
|
project-specific test related features through hooks. For example you may
|
2010-10-22 16:09:26 +08:00
|
|
|
set the ``collect_ignore`` variable depending on a command line option
|
2010-10-12 21:34:32 +08:00
|
|
|
by defining the following hook in a ``conftest.py`` file::
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
# ./conftest.py in your root or package dir
|
|
|
|
collect_ignore = ['hello', 'test_world.py']
|
2009-06-15 23:28:55 +08:00
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--runall", action="store_true", default=False)
|
|
|
|
def pytest_configure(config):
|
|
|
|
if config.getvalue("runall"):
|
|
|
|
collect_ignore[:] = []
|
|
|
|
|
2009-11-24 00:20:36 +08:00
|
|
|
.. _`setuptools entry points`:
|
2010-10-14 00:45:07 +08:00
|
|
|
.. _registered:
|
2009-11-24 00:20:36 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
Writing setuptools-registered plugins
|
2009-11-24 00:20:36 +08:00
|
|
|
------------------------------------------------------
|
|
|
|
|
|
|
|
.. _`Distribute`: http://pypi.python.org/pypi/distribute
|
|
|
|
.. _`setuptools`: http://pypi.python.org/pypi/setuptools
|
|
|
|
|
|
|
|
If you want to make your plugin publically available, you
|
|
|
|
can use `setuptools`_ or `Distribute`_ which both allow
|
|
|
|
to register an entry point. ``py.test`` will register
|
2010-07-27 03:15:15 +08:00
|
|
|
all objects with the ``pytest11`` entry point.
|
2009-11-24 00:20:36 +08:00
|
|
|
To make your plugin available you may insert the following
|
|
|
|
lines in your setuptools/distribute-based setup-invocation:
|
|
|
|
|
|
|
|
.. sourcecode:: python
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
# sample ./setup.py file
|
2009-11-24 00:20:36 +08:00
|
|
|
from setuptools import setup
|
|
|
|
|
|
|
|
setup(
|
|
|
|
name="myproject",
|
|
|
|
packages = ['myproject']
|
|
|
|
|
|
|
|
# the following makes a plugin available to py.test
|
2010-07-27 03:15:15 +08:00
|
|
|
entry_points = {
|
2009-11-24 00:20:36 +08:00
|
|
|
'pytest11': [
|
|
|
|
'name_of_plugin = myproject.pluginmodule',
|
|
|
|
]
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
If a package is installed with this setup, py.test will load
|
2009-11-24 00:20:36 +08:00
|
|
|
``myproject.pluginmodule`` under the ``name_of_plugin`` name
|
2010-07-27 03:15:15 +08:00
|
|
|
and use it as a plugin.
|
2009-11-24 00:20:36 +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")
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
If you want to look at the names of existing plugins, use
|
2009-11-24 00:20:36 +08:00
|
|
|
the ``--traceconfig`` option.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
.. _`well specified hooks`:
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-11 06:49:54 +08:00
|
|
|
py.test hook reference
|
2009-06-11 20:48:42 +08:00
|
|
|
====================================
|
|
|
|
|
2010-10-11 06:49:54 +08:00
|
|
|
hook specification and validation
|
|
|
|
-----------------------------------------
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2010-10-11 06:49:54 +08:00
|
|
|
py.test calls hook functions to implement initialization, running,
|
|
|
|
test execution and reporting. When py.test loads a plugin it validates
|
|
|
|
that all hook functions conform to their respective hook specification.
|
|
|
|
Each hook function name and its argument names need to match a hook
|
|
|
|
specification exactly but it is allowed for a hook function to accept
|
|
|
|
*less* parameters than specified. If you mistype argument names or the
|
|
|
|
hook name itself you get useful errors.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-11 06:49:54 +08:00
|
|
|
initialisation, command line and configuration hooks
|
2009-06-18 23:19:12 +08:00
|
|
|
--------------------------------------------------------------------
|
|
|
|
|
2010-10-11 06:49:54 +08:00
|
|
|
.. currentmodule:: pytest.hookspec
|
2009-06-18 23:19:12 +08:00
|
|
|
|
2010-10-12 21:34:32 +08:00
|
|
|
.. autofunction:: pytest_cmdline_parse
|
2010-10-11 06:49:54 +08:00
|
|
|
.. autofunction:: pytest_namespace
|
|
|
|
.. autofunction:: pytest_addoption
|
|
|
|
.. autofunction:: pytest_cmdline_main
|
|
|
|
.. autofunction:: pytest_configure
|
|
|
|
.. autofunction:: pytest_unconfigure
|
2009-06-18 23:19:12 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
generic "runtest" hooks
|
2009-06-15 21:15:40 +08:00
|
|
|
------------------------------
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-12 18:54:32 +08:00
|
|
|
All all runtest related hooks receive a :py:class:`pytest.collect.Item` object.
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
.. autofunction:: pytest_runtest_protocol
|
2010-10-11 06:49:54 +08:00
|
|
|
.. autofunction:: pytest_runtest_setup
|
|
|
|
.. autofunction:: pytest_runtest_call
|
|
|
|
.. autofunction:: pytest_runtest_teardown
|
2010-10-11 18:54:28 +08:00
|
|
|
.. autofunction:: pytest_runtest_makereport
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
For deeper understanding you may look at the default implementation of
|
|
|
|
these hooks in :py:mod:`pytest.plugin.runner` and maybe also
|
|
|
|
in :py:mod:`pytest.plugin.pdb` which intercepts creation
|
|
|
|
of reports in order to drop to interactive debugging.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
The :py:mod:`pytest.plugin.terminal` reported specifically uses
|
|
|
|
the reporting hook to print information about a test run.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
collection hooks
|
2009-06-15 21:15:40 +08:00
|
|
|
------------------------------
|
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
py.test calls the following hooks for collecting files and directories:
|
2009-06-15 23:28:55 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
.. autofunction:: pytest_ignore_collect
|
|
|
|
.. autofunction:: pytest_collect_directory
|
|
|
|
.. autofunction:: pytest_collect_file
|
2009-06-15 21:15:40 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
For influencing the collection of objects in Python modules
|
2009-06-15 21:15:40 +08:00
|
|
|
you can use the following hook:
|
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
.. autofunction:: pytest_pycollect_makeitem
|
2009-09-10 02:45:51 +08:00
|
|
|
|
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
reporting hooks
|
|
|
|
------------------------------
|
2009-09-10 02:45:51 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
Collection related reporting hooks:
|
2009-09-10 02:45:51 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
.. autofunction: pytest_collectstart
|
|
|
|
.. autofunction: pytest_log_itemcollect
|
|
|
|
.. autofunction: pytest_collectreport
|
|
|
|
.. autofunction: pytest_deselected
|
2009-09-10 02:45:51 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
And here is the central hook for reporting about
|
|
|
|
test execution:
|
2009-06-15 21:15:40 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
.. autofunction: pytest_runtest_logreport
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
The test collection tree
|
2010-07-27 03:15:15 +08:00
|
|
|
======================================================
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2009-08-19 01:04:57 +08:00
|
|
|
|
2010-10-11 18:54:28 +08:00
|
|
|
Default filesystem test discovery
|
|
|
|
-----------------------------------------------
|
|
|
|
|
|
|
|
Test collection starts from specified paths or from the current
|
|
|
|
directory. All tests are collected ahead of running the first test.
|
|
|
|
(This used to be different in earlier versions of ``py.test`` where
|
|
|
|
collection and running was interweaved which made test randomization
|
|
|
|
and distributed testing harder).
|
|
|
|
|
|
|
|
Collection nodes which have children are called "Collectors" and otherwise
|
|
|
|
they are called "Items" or "test items". Here is an example of such a
|
|
|
|
tree::
|
|
|
|
|
2010-10-11 19:38:16 +08:00
|
|
|
example $ py.test --collectonly test_collectonly.py
|
|
|
|
<Directory 'example'>
|
|
|
|
<Module 'test_collectonly.py'>
|
|
|
|
<Function 'test_function'>
|
|
|
|
<Class 'TestClass'>
|
2010-10-11 18:54:28 +08:00
|
|
|
<Instance '()'>
|
2010-10-11 19:38:16 +08:00
|
|
|
<Function 'test_method'>
|
|
|
|
<Function 'test_anothermethod'>
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
By default all directories not starting with a dot are traversed,
|
|
|
|
looking for ``test_*.py`` and ``*_test.py`` files. Those Python
|
|
|
|
files are imported under their `package name`_.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
The Module collector looks for test functions
|
2009-06-11 20:48:42 +08:00
|
|
|
and test classes and methods. Test functions and methods
|
2010-07-27 03:15:15 +08:00
|
|
|
are prefixed ``test`` by default. Test classes must
|
|
|
|
start with a capitalized ``Test`` prefix.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
Customizing error messages
|
2010-07-04 23:06:50 +08:00
|
|
|
-------------------------------------------------
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
On test and collection nodes ``py.test`` will invoke
|
2010-07-04 23:06:50 +08:00
|
|
|
the ``node.repr_failure(excinfo)`` function which
|
2010-07-27 03:15:15 +08:00
|
|
|
you may override and make it return an error
|
|
|
|
representation string of your choice. It
|
|
|
|
will be reported as a (red) string.
|
2010-07-04 23:06:50 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
.. _`package name`:
|
2009-06-11 20:48:42 +08:00
|
|
|
|
|
|
|
constructing the package name for test modules
|
|
|
|
-------------------------------------------------
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
Test modules are imported under their fully qualified
|
2009-06-11 20:48:42 +08:00
|
|
|
name. Given a filesystem ``fspath`` it is constructed as follows:
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
* walk the directories up to the last one that contains
|
|
|
|
an ``__init__.py`` file.
|
2009-06-11 20:48:42 +08:00
|
|
|
|
|
|
|
* perform ``sys.path.insert(0, basedir)``.
|
|
|
|
|
|
|
|
* import the root package as ``root``
|
2010-10-11 18:54:28 +08:00
|
|
|
|
2010-10-12 16:59:04 +08:00
|
|
|
Reference of important objects involved in hooks
|
2010-10-11 18:54:28 +08:00
|
|
|
===========================================================
|
|
|
|
|
2010-10-12 21:34:32 +08:00
|
|
|
.. autoclass:: pytest.plugin.config.Config
|
2010-10-11 18:54:28 +08:00
|
|
|
:members:
|
|
|
|
|
2010-10-12 18:54:32 +08:00
|
|
|
.. autoclass:: pytest.plugin.session.Item
|
2010-10-12 16:59:04 +08:00
|
|
|
:inherited-members:
|
2010-10-11 18:54:28 +08:00
|
|
|
|
2010-10-12 18:54:32 +08:00
|
|
|
.. autoclass:: pytest.plugin.session.Node
|
2010-10-11 18:54:28 +08:00
|
|
|
:members:
|
|
|
|
|
2010-10-12 16:59:04 +08:00
|
|
|
.. autoclass:: pytest.plugin.runner.CallInfo
|
|
|
|
:members:
|
|
|
|
|
|
|
|
.. autoclass:: pytest.plugin.runner.TestReport
|
|
|
|
:members:
|
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
|
|
|
|
conftest.py configuration files
|
|
|
|
=================================================
|
|
|
|
|
|
|
|
conftest.py reference docs
|
|
|
|
|
|
|
|
A unique feature of py.test are its ``conftest.py`` files which allow
|
|
|
|
project and directory specific customizations to testing.
|
|
|
|
|
|
|
|
* `set option defaults`_
|
|
|
|
|
|
|
|
or set particular variables to influence the testing process:
|
|
|
|
|
|
|
|
* ``pytest_plugins``: list of named plugins to load
|
|
|
|
|
|
|
|
* ``collect_ignore``: list of paths to ignore during test collection, relative to the containing ``conftest.py`` file
|
|
|
|
|
|
|
|
* ``rsyncdirs``: list of to-be-rsynced directories for distributed
|
|
|
|
testing, relative to the containing ``conftest.py`` file.
|
|
|
|
|
|
|
|
You may put a conftest.py files in your project root directory or into
|
|
|
|
your package directory if you want to add project-specific test options.
|
|
|
|
|
|
|
|
|
|
|
|
.. _`specify funcargs`: funcargs.html#application-setup-tutorial-example
|
|
|
|
|
|
|
|
.. _`set option defaults`:
|