2010-10-11 05:45:45 +08:00
|
|
|
|
2010-10-12 16:59:04 +08:00
|
|
|
.. _`captures`:
|
|
|
|
|
2011-03-04 06:40:38 +08:00
|
|
|
Capturing of the stdout/stderr output
|
2010-10-11 05:45:45 +08:00
|
|
|
=========================================================
|
|
|
|
|
2011-03-04 06:40:38 +08:00
|
|
|
Default stdout/stderr/stdin capturing behaviour
|
|
|
|
---------------------------------------------------------
|
|
|
|
|
|
|
|
During test execution any output sent to ``stdout`` and ``stderr`` is
|
|
|
|
captured. If a test or a setup method fails its according captured
|
2018-02-10 02:36:48 +08:00
|
|
|
output will usually be shown along with the failure traceback. (this
|
|
|
|
behavior can be configured by the ``--show-capture`` command-line option).
|
2011-03-04 06:40:38 +08:00
|
|
|
|
|
|
|
In addition, ``stdin`` is set to a "null" object which will
|
|
|
|
fail on attempts to read from it because it is rarely desired
|
|
|
|
to wait for interactive input when running automated tests.
|
|
|
|
|
|
|
|
By default capturing is done by intercepting writes to low level
|
|
|
|
file descriptors. This allows to capture output from simple
|
|
|
|
print statements as well as output from a subprocess started by
|
|
|
|
a test.
|
|
|
|
|
|
|
|
Setting capturing methods or disabling capturing
|
|
|
|
-------------------------------------------------
|
|
|
|
|
2014-01-18 19:31:33 +08:00
|
|
|
There are two ways in which ``pytest`` can perform capturing:
|
2011-03-04 06:40:38 +08:00
|
|
|
|
|
|
|
* file descriptor (FD) level capturing (default): All writes going to the
|
|
|
|
operating system file descriptors 1 and 2 will be captured.
|
|
|
|
|
|
|
|
* ``sys`` level capturing: Only writes to Python files ``sys.stdout``
|
|
|
|
and ``sys.stderr`` will be captured. No capturing of writes to
|
|
|
|
filedescriptors is performed.
|
|
|
|
|
|
|
|
.. _`disable capturing`:
|
|
|
|
|
2019-02-15 21:10:37 +08:00
|
|
|
You can influence output capturing mechanisms from the command line:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
2011-03-04 06:40:38 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
pytest -s # disable all capturing
|
|
|
|
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
|
|
|
|
pytest --capture=fd # also point filedescriptors 1 and 2 to temp file
|
2010-10-11 05:45:45 +08:00
|
|
|
|
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
|
2014-01-18 19:31:33 +08:00
|
|
|
|
2010-12-06 17:41:20 +08:00
|
|
|
def setup_function(function):
|
2018-11-22 16:15:14 +08:00
|
|
|
print("setting up %s" % function)
|
2010-12-06 17:41:20 +08:00
|
|
|
|
|
|
|
def test_func1():
|
|
|
|
assert True
|
|
|
|
|
|
|
|
def test_func2():
|
|
|
|
assert False
|
|
|
|
|
|
|
|
and running this module will show you precisely the output
|
2018-11-24 13:41:22 +08:00
|
|
|
of the failing function and hide the other one:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2010-12-06 17:41:20 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
$ pytest
|
2017-11-23 23:33:41 +08:00
|
|
|
=========================== test session starts ============================
|
2019-07-05 08:01:16 +08:00
|
|
|
platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y
|
2019-01-31 00:25:38 +08:00
|
|
|
cachedir: $PYTHON_PREFIX/.pytest_cache
|
2019-04-15 22:24:17 +08:00
|
|
|
rootdir: $REGENDOC_TMPDIR
|
2012-10-07 19:06:17 +08:00
|
|
|
collected 2 items
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2017-11-23 23:33:41 +08:00
|
|
|
test_module.py .F [100%]
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2017-11-23 23:33:41 +08:00
|
|
|
================================= FAILURES =================================
|
|
|
|
________________________________ test_func2 ________________________________
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2010-12-06 17:41:20 +08:00
|
|
|
def test_func2():
|
|
|
|
> assert False
|
|
|
|
E assert False
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2010-12-06 17:41:20 +08:00
|
|
|
test_module.py:9: AssertionError
|
2015-09-22 20:02:11 +08:00
|
|
|
-------------------------- Captured stdout setup ---------------------------
|
2015-06-07 05:30:49 +08:00
|
|
|
setting up <function test_func2 at 0xdeadbeef>
|
2017-11-23 23:33:41 +08:00
|
|
|
==================== 1 failed, 1 passed in 0.12 seconds ====================
|
2010-12-06 17:41:20 +08:00
|
|
|
|
2010-10-11 05:45:45 +08:00
|
|
|
Accessing captured output from a test function
|
|
|
|
---------------------------------------------------
|
|
|
|
|
2017-11-18 01:02:46 +08:00
|
|
|
The ``capsys``, ``capsysbinary``, ``capfd``, and ``capfdbinary`` fixtures
|
|
|
|
allow access to stdout/stderr output created during test execution. Here is
|
|
|
|
an example test function that performs some output related checks:
|
2015-07-10 08:50:38 +08:00
|
|
|
|
|
|
|
.. code-block:: python
|
2010-10-11 05:45:45 +08:00
|
|
|
|
2018-06-03 11:29:28 +08:00
|
|
|
def test_myoutput(capsys): # or use "capfd" for fd-level
|
2017-12-09 04:34:29 +08:00
|
|
|
print("hello")
|
2010-10-11 05:45:45 +08:00
|
|
|
sys.stderr.write("world\n")
|
2017-12-09 04:34:29 +08:00
|
|
|
captured = capsys.readouterr()
|
|
|
|
assert captured.out == "hello\n"
|
|
|
|
assert captured.err == "world\n"
|
|
|
|
print("next")
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
assert captured.out == "next\n"
|
2010-10-11 05:45:45 +08:00
|
|
|
|
|
|
|
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
|
2014-01-18 19:31:33 +08:00
|
|
|
output streams and also interacts well with pytest's
|
2010-10-11 05:45:45 +08:00
|
|
|
own per-test capturing.
|
|
|
|
|
2014-04-07 19:42:48 +08:00
|
|
|
If you want to capture on filedescriptor level you can use
|
2017-11-15 06:08:23 +08:00
|
|
|
the ``capfd`` fixture which offers the exact
|
2014-04-07 19:42:48 +08:00
|
|
|
same interface but allows to also capture output from
|
|
|
|
libraries or subprocesses that directly write to operating
|
|
|
|
system level output streams (FD1 and FD2).
|
2010-10-11 05:45:45 +08:00
|
|
|
|
2019-04-28 23:37:58 +08:00
|
|
|
|
2017-11-18 01:02:46 +08:00
|
|
|
|
2017-12-09 04:34:29 +08:00
|
|
|
The return value from ``readouterr`` changed to a ``namedtuple`` with two attributes, ``out`` and ``err``.
|
|
|
|
|
2019-04-28 23:37:58 +08:00
|
|
|
|
2017-12-09 04:34:29 +08:00
|
|
|
|
2017-11-18 01:02:46 +08:00
|
|
|
If the code under test writes non-textual data, you can capture this using
|
|
|
|
the ``capsysbinary`` fixture which instead returns ``bytes`` from
|
|
|
|
the ``readouterr`` method. The ``capfsysbinary`` fixture is currently only
|
|
|
|
available in python 3.
|
|
|
|
|
|
|
|
|
2019-04-28 23:37:58 +08:00
|
|
|
|
2017-11-15 06:08:23 +08:00
|
|
|
|
|
|
|
If the code under test writes non-textual data, you can capture this using
|
|
|
|
the ``capfdbinary`` fixture which instead returns ``bytes`` from
|
2017-11-18 01:02:46 +08:00
|
|
|
the ``readouterr`` method. The ``capfdbinary`` fixture operates on the
|
|
|
|
filedescriptor level.
|
2017-11-15 06:08:23 +08:00
|
|
|
|
2016-06-09 07:21:17 +08:00
|
|
|
|
2019-04-28 23:37:58 +08:00
|
|
|
|
2016-06-09 07:21:17 +08:00
|
|
|
|
|
|
|
To temporarily disable capture within a test, both ``capsys``
|
|
|
|
and ``capfd`` have a ``disabled()`` method that can be used
|
|
|
|
as a context manager, disabling capture inside the ``with`` block:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
def test_disabling_capturing(capsys):
|
2018-06-03 11:29:28 +08:00
|
|
|
print("this output is captured")
|
2016-06-09 07:21:17 +08:00
|
|
|
with capsys.disabled():
|
2018-06-03 11:29:28 +08:00
|
|
|
print("output not captured, going directly to sys.stdout")
|
|
|
|
print("this output is also captured")
|
2016-06-09 07:21:17 +08:00
|
|
|
|
2010-10-11 05:45:45 +08:00
|
|
|
.. include:: links.inc
|