2009-04-02 15:10:16 +08:00
==================================================
2010-07-27 03:15:15 +08:00
py.test feature overview
2009-03-23 18:01:15 +08:00
==================================================
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
.. contents::
2009-08-19 01:04:57 +08:00
:local:
:depth: 1
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
mature command line testing tool
2009-08-19 01:04:57 +08:00
====================================================
2009-04-13 21:58:26 +08:00
2010-01-18 23:18:59 +08:00
py.test is a command line tool to collect, run and report about automated tests. It runs well on Linux, Windows and OSX and on Python 2.4 through to 3.1 versions.
2010-07-27 03:15:15 +08:00
It is used in many projects, ranging from running 10 thousands of tests
2010-01-18 23:18:59 +08:00
to a few inlined tests on a command line script. As of version 1.2 you can also
generate a no-dependency py.test-equivalent standalone script that you
2010-07-27 03:15:15 +08:00
can distribute along with your application.
2009-04-13 21:58:26 +08:00
2010-07-27 03:15:15 +08:00
extensive easy plugin system
2010-01-18 23:18:59 +08:00
======================================================
.. _`suprisingly easy`: http://bruynooghe.blogspot.com/2009/12/skipping-slow-test-by-default-in-pytest.html
py.test delegates almost all aspects of its operation to plugins_.
It is `suprisingly easy`_ to add command line options or
2010-07-27 03:15:15 +08:00
do other kind of add-ons and customizations. This can
be done per-project or by distributing a global plugin.
One can can thus modify or add aspects for purposes such as:
2010-01-18 23:18:59 +08:00
* reporting extensions
2010-07-27 03:15:15 +08:00
* customizing collection and execution of tests
2010-01-18 23:18:59 +08:00
* running and managing non-python tests
2010-07-27 03:15:15 +08:00
* managing domain-specific test state setup
2010-01-18 23:18:59 +08:00
* adding non-python tests into the run, e.g. driven by data files
2009-07-21 00:54:08 +08:00
2010-01-18 23:18:59 +08:00
.. _`plugins`: plugin/index.html
2009-03-22 08:38:43 +08:00
2010-01-18 23:18:59 +08:00
distributing tests to your CPUs and SSH accounts
==========================================================
.. _`pytest-xdist`: plugin/xdist.html
Through the use of the separately released `pytest-xdist`_ plugin you
can seemlessly distribute runs to multiple CPUs or remote computers
through SSH and sockets. This plugin also offers a ``--looponfailing``
2010-07-27 03:15:15 +08:00
mode which will continously re-run only failing tests in a subprocess.
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
supports several testing practises and methods
2009-08-19 01:04:57 +08:00
==================================================================
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
py.test supports many testing methods conventionally used in
the Python community. It runs traditional `unittest.py`_,
2009-08-19 01:04:57 +08:00
`doctest.py`_, supports `xUnit style setup`_ and nose_ specific
2010-07-27 03:15:15 +08:00
setups and test suites. It offers minimal no-boilerplate model
for configuring and deploying tests written as simple Python
2009-08-19 01:04:57 +08:00
functions or methods. It also integrates `coverage testing
2010-07-27 03:15:15 +08:00
with figleaf`_ or `Javasript unit- and functional testing`_.
2009-03-22 08:38:43 +08:00
2009-08-19 01:04:57 +08:00
.. _`Javasript unit- and functional testing`: plugin/oejskit.html
.. _`coverage testing with figleaf`: plugin/figleaf.html
2009-03-22 08:38:43 +08:00
2010-01-18 23:18:59 +08:00
integrates well with CI systems
====================================================
py.test can produce JUnitXML style output as well as formatted
"resultlog" files that can be postprocessed by Continous Integration
2010-07-27 03:15:15 +08:00
systems such as Hudson or Buildbot easily. It also provides command
line options to control test configuration lookup behaviour or ignoring
certain tests or directories.
2010-01-18 23:18:59 +08:00
2010-07-27 03:15:15 +08:00
no-boilerplate test functions with Python
2009-08-19 01:04:57 +08:00
===================================================
2009-03-22 08:38:43 +08:00
2010-01-18 23:18:59 +08:00
.. _`autocollect`:
2010-07-27 03:15:15 +08:00
automatic Python test discovery
2009-08-19 01:04:57 +08:00
------------------------------------
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
By default, all python modules with a ``test_*.py``
2009-08-19 01:04:57 +08:00
filename are inspected for finding tests:
2009-03-22 08:38:43 +08:00
2009-08-19 01:04:57 +08:00
* functions with a name beginning with ``test_``
2010-07-27 03:15:15 +08:00
* classes with a leading ``Test`` name and ``test`` prefixed methods.
2009-08-19 01:04:57 +08:00
* ``unittest.TestCase`` subclasses
2009-03-22 08:38:43 +08:00
2010-07-09 02:13:39 +08:00
parametrizing test functions and functional testing
2010-01-18 23:18:59 +08:00
--------------------------------------------------------------
2009-06-09 22:08:34 +08:00
2009-08-19 01:04:57 +08:00
py.test offers the unique `funcargs mechanism`_ for setting up
2010-07-27 03:15:15 +08:00
and passing project-specific objects to Python test functions.
Test Parametrization happens by triggering a call to the same test
function with different argument values. For doing fixtures
using the funcarg mechanism makes your test and setup code
2010-01-18 23:18:59 +08:00
more efficient and more readable. This is especially true
for functional tests which might depend on command line
2010-07-27 03:15:15 +08:00
options and a setup that needs to be shared across
a whole test run.
2009-03-22 08:38:43 +08:00
2009-08-19 01:04:57 +08:00
per-test capturing of output, including subprocesses
----------------------------------------------------
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
By default, ``py.test`` captures all writes to stdout/stderr.
Output from ``print`` statements as well as from subprocesses
is captured_. When a test fails, the associated captured outputs are shown.
2009-08-19 01:04:57 +08:00
This allows you to put debugging print statements in your code without
being overwhelmed by all the output that might be generated by tests
that do not fail.
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
.. _captured: plugin/capture.html
2009-03-22 08:38:43 +08:00
2009-03-23 18:01:15 +08:00
assert with the ``assert`` statement
----------------------------------------
``py.test`` allows to use the standard python
2010-07-27 03:15:15 +08:00
``assert statement`` for verifying expectations
and values in Python tests. For example, you can
write the following in your tests::
2009-03-23 18:01:15 +08:00
2010-07-27 03:15:15 +08:00
assert hasattr(x, 'attribute')
2009-03-23 18:01:15 +08:00
to state that your object has a certain ``attribute``. In case this
assertion fails you will see the value of ``x``. Intermediate
2010-07-27 03:15:15 +08:00
values are computed by executing the assert expression a second time.
2009-03-23 18:01:15 +08:00
If you execute code with side effects, e.g. read from a file like this::
assert f.read() != '...'
then you may get a warning from pytest if that assertions
2010-07-27 03:15:15 +08:00
first failed and then succeeded.
2009-03-23 18:01:15 +08:00
2010-07-27 03:15:15 +08:00
asserting expected exceptions
2009-03-23 18:01:15 +08:00
----------------------------------------
2010-06-09 20:26:08 +08:00
In order to write assertions about exceptions, you can use
2010-07-27 03:15:15 +08:00
``py.test.raises`` as a context manager like this:
2010-07-08 21:28:54 +08:00
2010-07-27 03:15:15 +08:00
.. sourcecode:: python
2009-03-23 18:01:15 +08:00
2010-06-09 20:26:08 +08:00
with py.test.raises(ZeroDivisionError):
1 / 0
2010-07-08 21:28:54 +08:00
and if you need to have access to the actual exception info you may use:
2010-07-27 03:15:15 +08:00
.. sourcecode:: python
2010-06-09 20:45:41 +08:00
2010-07-27 03:15:15 +08:00
with py.test.raises(RuntimeError) as excinfo:
2010-06-09 20:45:41 +08:00
def f():
f()
f()
2010-07-27 03:15:15 +08:00
# do checks related to excinfo.type, excinfo.value, excinfo.traceback
2010-06-09 20:45:41 +08:00
2010-07-27 03:15:15 +08:00
If you want to write test code that works on Python2.4 as well,
2010-07-08 21:28:54 +08:00
you may also use two other ways to test for an expected exception:
2010-07-27 03:15:15 +08:00
.. sourcecode:: python
2010-06-09 20:26:08 +08:00
2010-07-27 03:15:15 +08:00
py.test.raises(ExpectedException, func, *args, **kwargs)
2010-06-09 20:26:08 +08:00
py.test.raises(ExpectedException, "func(*args, **kwargs)")
2009-03-23 18:01:15 +08:00
2009-08-19 01:04:57 +08:00
both of which execute the specified function with args and kwargs and
2010-06-09 20:26:08 +08:00
asserts that the given ``ExpectedException`` is raised. The reporter will
2009-03-23 18:01:15 +08:00
provide you with helpful output in case of failures such as *no
exception* or *wrong exception*.
2009-03-22 08:38:43 +08:00
2009-08-19 01:04:57 +08:00
information-rich tracebacks, PDB introspection
-------------------------------------------------------
2009-03-22 08:38:43 +08:00
2009-08-19 01:04:57 +08:00
.. _`example tracebacks`: http://paste.pocoo.org/show/134814/
2009-03-22 08:38:43 +08:00
2009-08-19 01:04:57 +08:00
A lot of care is taken to present useful failure information
and in particular nice and concise Python tracebacks. This
is especially useful if you need to regularly look at failures
from nightly runs, i.e. are detached from the actual test
running session. Here are `example tracebacks`_ for a number of failing
test functions. You can modify traceback printing styles through the
command line. Using the `--pdb`` option you can automatically activate
2010-07-27 03:15:15 +08:00
a PDB `Python debugger`_ when a test fails.
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
skip or expect-to-fail a test
2009-10-16 02:10:06 +08:00
======================================
2009-03-22 08:38:43 +08:00
2010-07-09 02:13:39 +08:00
py.test has a dedicated `skipping plugin`_ that allows to define
2009-03-22 08:38:43 +08:00
2010-07-27 03:15:15 +08:00
* define "skip" outcomes indicating a platform or a
dependency mismatch.
2010-07-09 02:13:39 +08:00
2010-07-27 03:15:15 +08:00
* "xfail" outcomes indicating an "expected failure" either with
with or without running a test.
2010-07-09 02:13:39 +08:00
* skip and xfail outcomes can be applied at module, class or method
2010-07-27 03:15:15 +08:00
level or even only for certain argument sets of a parametrized function.
2010-07-09 02:13:39 +08:00
.. _`skipping plugin`: plugin/skipping.html
2009-08-19 01:04:57 +08:00
.. _`funcargs mechanism`: funcargs.html
.. _`unittest.py`: http://docs.python.org/library/unittest.html
.. _`doctest.py`: http://docs.python.org/library/doctest.html
.. _`xUnit style setup`: xunit_setup.html
.. _`pytest_nose`: plugin/nose.html
2009-03-23 18:01:15 +08:00
2010-07-27 03:15:15 +08:00
select tests by keyword / test name search
2009-08-19 01:04:57 +08:00
=========================================================
2009-03-23 18:01:15 +08:00
2010-07-27 03:15:15 +08:00
.. _`selection by keyword`:
2009-03-23 18:01:15 +08:00
2010-07-27 03:15:15 +08:00
You can selectively run tests by specifiying a keyword
2009-03-23 18:01:15 +08:00
on the command line. Examples::
2010-07-27 03:15:15 +08:00
py.test -k test_simple
2009-03-23 18:01:15 +08:00
py.test -k "-test_simple"
will run all tests matching (or not matching) the
2010-07-27 03:15:15 +08:00
"test_simple" keyword. Note that you need to quote
the keyword if "-" is recognized as an indicator
2009-03-23 18:01:15 +08:00
for a commandline option. Lastly, you may use::
py.test. -k "test_simple:"
2010-07-27 03:15:15 +08:00
which will run all tests after the expression has *matched once*, i.e.
all tests that are seen after a test that matches the "test_simple"
keyword.
2009-03-23 18:01:15 +08:00
By default, all filename parts and
class/function names of a test function are put into the set
2010-07-27 03:15:15 +08:00
of keywords for a given test. You can specify additional
2010-07-08 21:28:54 +08:00
kewords like this:
2010-07-27 03:15:15 +08:00
.. sourcecode:: python
2009-03-23 18:01:15 +08:00
2010-07-27 03:15:15 +08:00
@py.test.mark.webtest
2009-03-23 18:01:15 +08:00
def test_send_http():
2010-07-27 03:15:15 +08:00
...
2009-03-23 18:01:15 +08:00
2009-07-28 20:26:32 +08:00
and then use those keywords to select tests. See the `pytest_keyword`_
2010-07-27 03:15:15 +08:00
plugin for more information.
2009-07-28 20:26:32 +08:00
2009-10-23 02:57:21 +08:00
.. _`pytest_keyword`: plugin/mark.html
2009-07-28 20:26:32 +08:00
2010-07-27 03:15:15 +08:00
Looping on the failing test set
2010-07-09 02:13:39 +08:00
=======================================
``py.test --looponfailing`` (implemented through the external
2010-07-27 03:15:15 +08:00
`pytest-xdist`_ plugin) allows to run a test suite,
2010-07-09 02:13:39 +08:00
memorize all failures and then loop over the failing set
of tests until they all pass. It will re-start running
2010-07-27 03:15:15 +08:00
the tests when it detects file changes in your project.
2010-07-09 02:13:39 +08:00
2009-03-22 08:38:43 +08:00
.. _`reStructured Text`: http://docutils.sourceforge.net
.. _`Python debugger`: http://docs.python.org/lib/module-pdb.html
.. _nose: http://somethingaboutorange.com/mrl/projects/nose/