commit
890c2fa555
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
*
|
* Minor improvements and fixes to the documentation.
|
||||||
|
Thanks `@omarkohl`_ for the PR.
|
||||||
|
|
||||||
|
|
||||||
2.9.1
|
2.9.1
|
||||||
|
@ -163,6 +164,7 @@
|
||||||
.. _@RonnyPfannschmidt: https://github.com/RonnyPfannschmidt
|
.. _@RonnyPfannschmidt: https://github.com/RonnyPfannschmidt
|
||||||
.. _@rabbbit: https://github.com/rabbbit
|
.. _@rabbbit: https://github.com/rabbbit
|
||||||
.. _@hackebrot: https://github.com/hackebrot
|
.. _@hackebrot: https://github.com/hackebrot
|
||||||
|
.. _@omarkohl: https://github.com/omarkohl
|
||||||
|
|
||||||
2.8.7
|
2.8.7
|
||||||
=====
|
=====
|
||||||
|
|
|
@ -177,16 +177,27 @@ and a setup.py dummy file like this::
|
||||||
# content of setup.py
|
# content of setup.py
|
||||||
0/0 # will raise exception if imported
|
0/0 # will raise exception if imported
|
||||||
|
|
||||||
then a pytest run on python2 will find the one test when run with a python2
|
then a pytest run on Python2 will find the one test and will leave out the
|
||||||
interpreters and will leave out the setup.py file::
|
setup.py file::
|
||||||
|
|
||||||
$ py.test --collect-only
|
$ py.test --collect-only
|
||||||
======= test session starts ========
|
====== test session starts ======
|
||||||
platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
|
platform linux2 -- Python 2.7.10, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
|
||||||
|
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
|
||||||
|
collected 1 items
|
||||||
|
<Module 'pkg/module_py2.py'>
|
||||||
|
<Function 'test_only_on_python2'>
|
||||||
|
|
||||||
|
====== no tests ran in 0.04 seconds ======
|
||||||
|
|
||||||
|
If you run with a Python3 interpreter both the one test and the setup.py file
|
||||||
|
will be left out::
|
||||||
|
|
||||||
|
$ py.test --collect-only
|
||||||
|
====== test session starts ======
|
||||||
|
platform linux -- Python 3.4.3+, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
|
||||||
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
|
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
|
||||||
collected 0 items
|
collected 0 items
|
||||||
|
|
||||||
======= no tests ran in 0.12 seconds ========
|
====== no tests ran in 0.03 seconds ======
|
||||||
|
|
||||||
If you run with a Python3 interpreter the moduled added through the conftest.py file will not be considered for test collection.
|
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ Example::
|
||||||
|
|
||||||
The ``__tracebackhide__`` setting influences ``pytest`` showing
|
The ``__tracebackhide__`` setting influences ``pytest`` showing
|
||||||
of tracebacks: the ``checkconfig`` function will not be shown
|
of tracebacks: the ``checkconfig`` function will not be shown
|
||||||
unless the ``--fulltrace`` command line option is specified.
|
unless the ``--full-trace`` command line option is specified.
|
||||||
Let's run our little function::
|
Let's run our little function::
|
||||||
|
|
||||||
$ py.test -q test_checkconfig.py
|
$ py.test -q test_checkconfig.py
|
||||||
|
|
|
@ -36,9 +36,9 @@ style <unittest.TestCase>` or :ref:`nose based <nosestyle>` projects.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
pytest-2.4 introduced an additional experimental
|
pytest-2.4 introduced an additional :ref:`yield fixture mechanism
|
||||||
:ref:`yield fixture mechanism <yieldfixture>` for easier context manager
|
<yieldfixture>` for easier context manager integration and more linear
|
||||||
integration and more linear writing of teardown code.
|
writing of teardown code.
|
||||||
|
|
||||||
.. _`funcargs`:
|
.. _`funcargs`:
|
||||||
.. _`funcarg mechanism`:
|
.. _`funcarg mechanism`:
|
||||||
|
@ -283,6 +283,14 @@ module itself does not need to change or know about these details
|
||||||
of fixture setup.
|
of fixture setup.
|
||||||
|
|
||||||
|
|
||||||
|
Finalization/teardown with yield fixtures
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Another alternative to the *request.addfinalizer()* method is to use *yield
|
||||||
|
fixtures*. All the code after the *yield* statement serves as the teardown
|
||||||
|
code. See the :ref:`yield fixture documentation <yieldfixture>`.
|
||||||
|
|
||||||
|
|
||||||
.. _`request-context`:
|
.. _`request-context`:
|
||||||
|
|
||||||
Fixtures can introspect the requesting test context
|
Fixtures can introspect the requesting test context
|
||||||
|
@ -577,55 +585,85 @@ to show the setup/teardown flow::
|
||||||
@pytest.fixture(scope="module", params=["mod1", "mod2"])
|
@pytest.fixture(scope="module", params=["mod1", "mod2"])
|
||||||
def modarg(request):
|
def modarg(request):
|
||||||
param = request.param
|
param = request.param
|
||||||
print ("create", param)
|
print (" SETUP modarg %s" % param)
|
||||||
def fin():
|
def fin():
|
||||||
print ("fin %s" % param)
|
print (" TEARDOWN modarg %s" % param)
|
||||||
|
request.addfinalizer(fin)
|
||||||
return param
|
return param
|
||||||
|
|
||||||
@pytest.fixture(scope="function", params=[1,2])
|
@pytest.fixture(scope="function", params=[1,2])
|
||||||
def otherarg(request):
|
def otherarg(request):
|
||||||
return request.param
|
param = request.param
|
||||||
|
print (" SETUP otherarg %s" % param)
|
||||||
|
def fin():
|
||||||
|
print (" TEARDOWN otherarg %s" % param)
|
||||||
|
request.addfinalizer(fin)
|
||||||
|
return param
|
||||||
|
|
||||||
def test_0(otherarg):
|
def test_0(otherarg):
|
||||||
print (" test0", otherarg)
|
print (" RUN test0 with otherarg %s" % otherarg)
|
||||||
def test_1(modarg):
|
def test_1(modarg):
|
||||||
print (" test1", modarg)
|
print (" RUN test1 with modarg %s" % modarg)
|
||||||
def test_2(otherarg, modarg):
|
def test_2(otherarg, modarg):
|
||||||
print (" test2", otherarg, modarg)
|
print (" RUN test2 with otherarg %s and modarg %s" % (otherarg, modarg))
|
||||||
|
|
||||||
|
|
||||||
Let's run the tests in verbose mode and with looking at the print-output::
|
Let's run the tests in verbose mode and with looking at the print-output::
|
||||||
|
|
||||||
$ py.test -v -s test_module.py
|
$ py.test -v -s test_module.py
|
||||||
======= test session starts ========
|
====== test session starts ======
|
||||||
platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
|
platform linux -- Python 3.4.3+, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3
|
||||||
cachedir: .cache
|
cachedir: .cache
|
||||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||||
collecting ... collected 8 items
|
collected 8 items
|
||||||
|
|
||||||
test_module.py::test_0[1] test0 1
|
test_module.py::test_0[1] SETUP otherarg 1
|
||||||
PASSED
|
RUN test0 with otherarg 1
|
||||||
test_module.py::test_0[2] test0 2
|
PASSED TEARDOWN otherarg 1
|
||||||
PASSED
|
|
||||||
test_module.py::test_1[mod1] create mod1
|
|
||||||
test1 mod1
|
|
||||||
PASSED
|
|
||||||
test_module.py::test_2[1-mod1] test2 1 mod1
|
|
||||||
PASSED
|
|
||||||
test_module.py::test_2[2-mod1] test2 2 mod1
|
|
||||||
PASSED
|
|
||||||
test_module.py::test_1[mod2] create mod2
|
|
||||||
test1 mod2
|
|
||||||
PASSED
|
|
||||||
test_module.py::test_2[1-mod2] test2 1 mod2
|
|
||||||
PASSED
|
|
||||||
test_module.py::test_2[2-mod2] test2 2 mod2
|
|
||||||
PASSED
|
|
||||||
|
|
||||||
======= 8 passed in 0.12 seconds ========
|
test_module.py::test_0[2] SETUP otherarg 2
|
||||||
|
RUN test0 with otherarg 2
|
||||||
|
PASSED TEARDOWN otherarg 2
|
||||||
|
|
||||||
You can see that the parametrized module-scoped ``modarg`` resource caused
|
test_module.py::test_1[mod1] SETUP modarg mod1
|
||||||
an ordering of test execution that lead to the fewest possible "active" resources. The finalizer for the ``mod1`` parametrized resource was executed
|
RUN test1 with modarg mod1
|
||||||
before the ``mod2`` resource was setup.
|
PASSED
|
||||||
|
test_module.py::test_2[1-mod1] SETUP otherarg 1
|
||||||
|
RUN test2 with otherarg 1 and modarg mod1
|
||||||
|
PASSED TEARDOWN otherarg 1
|
||||||
|
|
||||||
|
test_module.py::test_2[2-mod1] SETUP otherarg 2
|
||||||
|
RUN test2 with otherarg 2 and modarg mod1
|
||||||
|
PASSED TEARDOWN otherarg 2
|
||||||
|
|
||||||
|
test_module.py::test_1[mod2] TEARDOWN modarg mod1
|
||||||
|
SETUP modarg mod2
|
||||||
|
RUN test1 with modarg mod2
|
||||||
|
PASSED
|
||||||
|
test_module.py::test_2[1-mod2] SETUP otherarg 1
|
||||||
|
RUN test2 with otherarg 1 and modarg mod2
|
||||||
|
PASSED TEARDOWN otherarg 1
|
||||||
|
|
||||||
|
test_module.py::test_2[2-mod2] SETUP otherarg 2
|
||||||
|
RUN test2 with otherarg 2 and modarg mod2
|
||||||
|
PASSED TEARDOWN otherarg 2
|
||||||
|
TEARDOWN modarg mod2
|
||||||
|
|
||||||
|
|
||||||
|
====== 8 passed in 0.01 seconds ======
|
||||||
|
|
||||||
|
|
||||||
|
You can see that the parametrized module-scoped ``modarg`` resource caused an
|
||||||
|
ordering of test execution that lead to the fewest possible "active" resources.
|
||||||
|
The finalizer for the ``mod1`` parametrized resource was executed before the
|
||||||
|
``mod2`` resource was setup.
|
||||||
|
|
||||||
|
In particular notice that test_0 is completely independent and finishes first.
|
||||||
|
Then test_1 is executed with ``mod1``, then test_2 with ``mod1``, then test_1
|
||||||
|
with ``mod2`` and finally test_2 with ``mod2``.
|
||||||
|
|
||||||
|
The ``otherarg`` parametrized resource (having function scope) was set up before
|
||||||
|
and teared down after every test that used it.
|
||||||
|
|
||||||
|
|
||||||
.. _`usefixtures`:
|
.. _`usefixtures`:
|
||||||
|
|
|
@ -153,7 +153,9 @@ against your source code checkout, helping to detect packaging
|
||||||
glitches.
|
glitches.
|
||||||
|
|
||||||
Continuous integration services such as Jenkins_ can make use of the
|
Continuous integration services such as Jenkins_ can make use of the
|
||||||
``--junitxml=PATH`` option to create a JUnitXML file and generate reports.
|
``--junitxml=PATH`` option to create a JUnitXML file and generate reports (e.g.
|
||||||
|
by publishing the results in a nice format with the `Jenkins xUnit Plugin
|
||||||
|
<https://wiki.jenkins-ci.org/display/JENKINS/xUnit+Plugin>`_).
|
||||||
|
|
||||||
|
|
||||||
Integrating with setuptools / ``python setup.py test`` / ``pytest-runner``
|
Integrating with setuptools / ``python setup.py test`` / ``pytest-runner``
|
||||||
|
|
|
@ -90,7 +90,7 @@ Finding out which plugins are active
|
||||||
If you want to find out which plugins are active in your
|
If you want to find out which plugins are active in your
|
||||||
environment you can type::
|
environment you can type::
|
||||||
|
|
||||||
py.test --traceconfig
|
py.test --trace-config
|
||||||
|
|
||||||
and will get an extended test header which shows activated plugins
|
and will get an extended test header which shows activated plugins
|
||||||
and their names. It will also print local plugins aka
|
and their names. It will also print local plugins aka
|
||||||
|
|
|
@ -21,7 +21,7 @@ but note that project specific settings will be considered
|
||||||
first. There is a flag that helps you debugging your
|
first. There is a flag that helps you debugging your
|
||||||
conftest.py configurations::
|
conftest.py configurations::
|
||||||
|
|
||||||
py.test --traceconfig
|
py.test --trace-config
|
||||||
|
|
||||||
|
|
||||||
customizing the collecting and running process
|
customizing the collecting and running process
|
||||||
|
|
|
@ -16,7 +16,7 @@ command line options
|
||||||
display py lib version and import information.
|
display py lib version and import information.
|
||||||
``-p name``
|
``-p name``
|
||||||
early-load given plugin (multi-allowed).
|
early-load given plugin (multi-allowed).
|
||||||
``--traceconfig``
|
``--trace-config``
|
||||||
trace considerations of conftest.py files.
|
trace considerations of conftest.py files.
|
||||||
``--nomagic``
|
``--nomagic``
|
||||||
don't reinterpret asserts, no traceback cutting.
|
don't reinterpret asserts, no traceback cutting.
|
||||||
|
|
|
@ -22,7 +22,7 @@ command line options
|
||||||
(deprecated, use -r)
|
(deprecated, use -r)
|
||||||
``--tb=style``
|
``--tb=style``
|
||||||
traceback print mode (long/short/line/no).
|
traceback print mode (long/short/line/no).
|
||||||
``--fulltrace``
|
``--full-trace``
|
||||||
don't cut any tracebacks (default is to cut).
|
don't cut any tracebacks (default is to cut).
|
||||||
``--fixtures``
|
``--fixtures``
|
||||||
show available function arguments, sorted by plugin
|
show available function arguments, sorted by plugin
|
||||||
|
|
|
@ -56,7 +56,7 @@ Several test run options::
|
||||||
|
|
||||||
Import 'pkg' and use its filesystem location to find and run tests::
|
Import 'pkg' and use its filesystem location to find and run tests::
|
||||||
|
|
||||||
py.test --pyargs pkg # run all tests found below directory of pypkg
|
py.test --pyargs pkg # run all tests found below directory of pkg
|
||||||
|
|
||||||
Modifying Python traceback printing
|
Modifying Python traceback printing
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
@ -74,6 +74,14 @@ Examples for modifying traceback printing::
|
||||||
py.test --tb=native # Python standard library formatting
|
py.test --tb=native # Python standard library formatting
|
||||||
py.test --tb=no # no traceback at all
|
py.test --tb=no # no traceback at all
|
||||||
|
|
||||||
|
The ``--full-trace`` causes very long traces to be printed on error (longer
|
||||||
|
than ``--tb=long``). It also ensures that a stack trace is printed on
|
||||||
|
**KeyboardInterrrupt** (Ctrl+C).
|
||||||
|
This is very useful if the tests are taking too long and you interrupt them
|
||||||
|
with Ctrl+C to find out where the tests are *hanging*. By default no output
|
||||||
|
will be shown (because KeyboardInterrupt is catched by pytest). By using this
|
||||||
|
option you make sure a trace is shown.
|
||||||
|
|
||||||
Dropping to PDB_ (Python Debugger) on failures
|
Dropping to PDB_ (Python Debugger) on failures
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ reporting by calling `well specified hooks`_ of the following plugins:
|
||||||
|
|
||||||
In principle, each hook call is a ``1:N`` Python function call where ``N`` is the
|
In principle, each hook call is a ``1:N`` Python function call where ``N`` is the
|
||||||
number of registered implementation functions for a given specification.
|
number of registered implementation functions for a given specification.
|
||||||
All specifications and implementations following the ``pytest_`` prefix
|
All specifications and implementations follow the ``pytest_`` prefix
|
||||||
naming convention, making them easy to distinguish and find.
|
naming convention, making them easy to distinguish and find.
|
||||||
|
|
||||||
.. _`pluginorder`:
|
.. _`pluginorder`:
|
||||||
|
@ -194,7 +194,7 @@ the plugin manager like this:
|
||||||
plugin = config.pluginmanager.getplugin("name_of_plugin")
|
plugin = config.pluginmanager.getplugin("name_of_plugin")
|
||||||
|
|
||||||
If you want to look at the names of existing plugins, use
|
If you want to look at the names of existing plugins, use
|
||||||
the ``--traceconfig`` option.
|
the ``--trace-config`` option.
|
||||||
|
|
||||||
Testing plugins
|
Testing plugins
|
||||||
---------------
|
---------------
|
||||||
|
|
Loading…
Reference in New Issue