2010-10-11 05:45:45 +08:00
|
|
|
|
2010-10-12 16:59:04 +08:00
|
|
|
.. _`captures`:
|
|
|
|
|
2010-10-11 05:45:45 +08:00
|
|
|
Capturing of stdout/stderr output
|
|
|
|
=========================================================
|
|
|
|
|
|
|
|
By default ``stdout`` and ``stderr`` output is captured separately for
|
|
|
|
setup and test execution code. If a test or a setup method fails its
|
|
|
|
according output will usually be shown along with the failure traceback.
|
|
|
|
In addition, ``stdin`` is set to a "null" object which will fail all
|
|
|
|
attempts to read from it. This is important if some code paths in
|
|
|
|
test otherwise might lead to waiting for input - which is usually
|
|
|
|
not desired when running automated tests.
|
|
|
|
|
2010-12-06 17:41:20 +08:00
|
|
|
.. _printdebugging:
|
|
|
|
|
|
|
|
Using print statements for debugging
|
|
|
|
---------------------------------------------------
|
|
|
|
|
|
|
|
One primary benefit of the default capturing of stdout/stderr output
|
|
|
|
is that you can use print statements for debugging::
|
|
|
|
|
|
|
|
# content of test_module.py
|
|
|
|
|
|
|
|
def setup_function(function):
|
|
|
|
print ("setting up %s" % function)
|
|
|
|
|
|
|
|
def test_func1():
|
|
|
|
assert True
|
|
|
|
|
|
|
|
def test_func2():
|
|
|
|
assert False
|
|
|
|
|
|
|
|
and running this module will show you precisely the output
|
|
|
|
of the failing function and hide the other one::
|
|
|
|
|
|
|
|
$ py.test
|
|
|
|
=========================== test session starts ============================
|
|
|
|
platform linux2 -- Python 2.6.5 -- pytest-2.0.1.dev1
|
|
|
|
collecting ... collected 2 items
|
|
|
|
|
|
|
|
test_module.py .F
|
|
|
|
|
|
|
|
================================= FAILURES =================================
|
|
|
|
________________________________ test_func2 ________________________________
|
|
|
|
|
|
|
|
def test_func2():
|
|
|
|
> assert False
|
|
|
|
E assert False
|
|
|
|
|
|
|
|
test_module.py:9: AssertionError
|
|
|
|
----------------------------- Captured stdout ------------------------------
|
|
|
|
setting up <function test_func2 at 0x1e6cd70>
|
|
|
|
==================== 1 failed, 1 passed in 0.04 seconds ====================
|
|
|
|
|
2010-10-11 05:45:45 +08:00
|
|
|
Setting capturing methods or disabling capturing
|
|
|
|
-------------------------------------------------
|
|
|
|
|
|
|
|
There are two ways in which ``py.test`` can perform capturing:
|
|
|
|
|
2010-11-25 19:11:10 +08:00
|
|
|
* ``fd`` level capturing (default): All writes going to the operating
|
|
|
|
system file descriptors 1 and 2 will be captured, for example writes such
|
|
|
|
as ``os.write(1, 'hello')``. Capturing on ``fd``-level also includes
|
2010-10-11 05:45:45 +08:00
|
|
|
**output from subprocesses**.
|
|
|
|
|
2010-11-25 19:11:10 +08:00
|
|
|
* ``sys`` level capturing: The ``sys.stdout`` and ``sys.stderr`` will
|
2010-10-11 05:45:45 +08:00
|
|
|
will be replaced with in-memory files and the ``print`` builtin or
|
2010-11-25 19:11:10 +08:00
|
|
|
output from code like ``sys.stderr.write(...)`` will be captured with
|
2010-10-11 05:45:45 +08:00
|
|
|
this method.
|
|
|
|
|
2010-10-12 16:59:04 +08:00
|
|
|
.. _`disable capturing`:
|
2010-10-11 05:45:45 +08:00
|
|
|
|
|
|
|
You can influence output capturing mechanisms from the command line::
|
|
|
|
|
|
|
|
py.test -s # disable all capturing
|
|
|
|
py.test --capture=sys # replace sys.stdout/stderr with in-mem files
|
|
|
|
py.test --capture=fd # also point filedescriptors 1 and 2 to temp file
|
|
|
|
|
2010-11-25 19:11:10 +08:00
|
|
|
|
2010-10-11 05:45:45 +08:00
|
|
|
Accessing captured output from a test function
|
|
|
|
---------------------------------------------------
|
|
|
|
|
2010-10-11 06:14:32 +08:00
|
|
|
The :ref:`funcarg mechanism` allows test function a very easy
|
2010-10-11 05:45:45 +08:00
|
|
|
way to access the captured output by simply using the names
|
|
|
|
``capsys`` or ``capfd`` in the test function signature. Here
|
|
|
|
is an example test function that performs some output related
|
|
|
|
checks::
|
|
|
|
|
|
|
|
def test_myoutput(capsys): # or use "capfd" for fd-level
|
|
|
|
print ("hello")
|
|
|
|
sys.stderr.write("world\n")
|
|
|
|
out, err = capsys.readouterr()
|
|
|
|
assert out == "hello\n"
|
|
|
|
assert err == "world\n"
|
|
|
|
print "next"
|
|
|
|
out, err = capsys.readouterr()
|
|
|
|
assert out == "next\n"
|
|
|
|
|
|
|
|
The ``readouterr()`` call snapshots the output so far -
|
|
|
|
and capturing will be continued. After the test
|
|
|
|
function finishes the original streams will
|
|
|
|
be restored. Using ``capsys`` this way frees your
|
|
|
|
test from having to care about setting/resetting
|
|
|
|
output streams and also interacts well with py.test's
|
|
|
|
own per-test capturing.
|
|
|
|
|
|
|
|
If you want to capture on ``fd`` level you can use
|
|
|
|
the ``capfd`` function argument which offers the exact
|
|
|
|
same interface.
|
|
|
|
|
|
|
|
.. include:: links.inc
|