Merge pull request #2593 from hackebrot/extend-pytester-docs-for-testing-plugin-code

Extend pytester docs for testing plugin code
This commit is contained in:
Bruno Oliveira 2017-07-19 16:40:00 -03:00 committed by GitHub
commit 61d4345ea4
2 changed files with 91 additions and 23 deletions

1
changelog/971.doc Normal file
View File

@ -0,0 +1 @@
Extend documentation for testing plugin code with the ``pytester`` plugin.

View File

@ -122,8 +122,8 @@ to extend and add functionality.
for authoring plugins. for authoring plugins.
The template provides an excellent starting point with a working plugin, The template provides an excellent starting point with a working plugin,
tests running with tox, comprehensive README and tests running with tox, a comprehensive README file as well as a
entry-pointy already pre-configured. pre-configured entry-point.
Also consider :ref:`contributing your plugin to pytest-dev<submitplugin>` Also consider :ref:`contributing your plugin to pytest-dev<submitplugin>`
once it has some happy users other than yourself. once it has some happy users other than yourself.
@ -286,34 +286,101 @@ the ``--trace-config`` option.
Testing plugins Testing plugins
--------------- ---------------
pytest comes with some facilities that you can enable for testing your pytest comes with a plugin named ``pytester`` that helps you write tests for
plugin. Given that you have an installed plugin you can enable the your plugin code. The plugin is disabled by default, so you will have to enable
:py:class:`testdir <_pytest.pytester.Testdir>` fixture via specifying a it before you can use it.
command line option to include the pytester plugin (``-p pytester``) or
by putting ``pytest_plugins = "pytester"`` into your test or
``conftest.py`` file. You then will have a ``testdir`` fixture which you
can use like this::
# content of test_myplugin.py You can do so by adding the following line to a ``conftest.py`` file in your
testing directory:
pytest_plugins = "pytester" # to get testdir fixture .. code-block:: python
def test_myplugin(testdir): # content of conftest.py
pytest_plugins = ["pytester"]
Alternatively you can invoke pytest with the ``-p pytester`` command line
option.
This will allow you to use the :py:class:`testdir <_pytest.pytester.Testdir>`
fixture for testing your plugin code.
Let's demonstrate what you can do with the plugin with an example. Imagine we
developed a plugin that provides a fixture ``hello`` which yields a function
and we can invoke this function with one optional parameter. It will return a
string value of ``Hello World!`` if we do not supply a value or ``Hello
{value}!`` if we do supply a string value.
.. code-block:: python
# -*- coding: utf-8 -*-
import pytest
def pytest_addoption(parser):
group = parser.getgroup('helloworld')
group.addoption(
'--name',
action='store',
dest='name',
default='World',
help='Default "name" for hello().'
)
@pytest.fixture
def hello(request):
name = request.config.option.name
def _hello(name=None):
if not name:
name = request.config.option.name
return "Hello {name}!".format(name=name)
return _hello
Now the ``testdir`` fixture provides a convenient API for creating temporary
``conftest.py`` files and test files. It also allows us to run the tests and
return a result object, with which we can assert the tests' outcomes.
.. code-block:: python
def test_hello(testdir):
"""Make sure that our plugin works."""
# create a temporary conftest.py file
testdir.makeconftest("""
import pytest
@pytest.fixture(params=[
"Brianna",
"Andreas",
"Floris",
])
def name(request):
return request.param
""")
# create a temporary pytest test file
testdir.makepyfile(""" testdir.makepyfile("""
def test_example(): def test_hello_default(hello):
pass assert hello() == "Hello World!"
""")
result = testdir.runpytest("--verbose") def test_hello_name(hello, name):
result.stdout.fnmatch_lines(""" assert hello(name) == "Hello {0}!".format(name)
test_example*
""") """)
Note that by default ``testdir.runpytest()`` will perform a pytest # run all tests with pytest
in-process. You can pass the command line option ``--runpytest=subprocess`` result = testdir.runpytest()
to have it happen in a subprocess.
# check that all 4 tests passed
result.assert_outcomes(passed=4)
For more information about the result object that ``runpytest()`` returns, and
the methods that it provides please check out the :py:class:`RunResult
<_pytest.pytester.RunResult>` documentation.
Also see the :py:class:`RunResult <_pytest.pytester.RunResult>` for more
methods of the result object that you get from a call to ``runpytest``.
.. _`writinghooks`: .. _`writinghooks`: