File: streams.txt

package info (click to toggle)
python-testfixtures 8.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,064 kB
  • sloc: python: 10,208; makefile: 76; sh: 9
file content (98 lines) | stat: -rw-r--r-- 2,751 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Testing output to streams
=========================

.. currentmodule:: testfixtures

In many situations, it's perfectly legitimate for output to be printed
to one of the standard streams. To aid with testing this kind of
output, testfixtures provides the :class:`OutputCapture` helper.

This helper is a context manager that captures output sent to
``sys.stdout`` and ``sys.stderr`` and provides a
:meth:`~OutputCapture.compare` method to check that the output was as
expected.

Here's a simple example:

.. code-block:: python

  from testfixtures import OutputCapture
  import sys

  with OutputCapture() as output:
      # code under test
      print("Hello!")
      print("Something bad happened!", file=sys.stderr)

  output.compare('\n'.join([
      "Hello!",
      "Something bad happened!",
  ]))

To make life easier, both the actual and expected output are stripped
of leading and trailing whitespace before the comparison is done:

>>> with OutputCapture() as o:
...    print('  Bar! ')
...    o.compare(' Foo!  ')
Traceback (most recent call last):
...
AssertionError: 'Foo!' (expected) != 'Bar!' (actual)

However, if you need to make very explicit assertions about what has
been written to the stream then you can do so using the `captured`
property of the :class:`OutputCapture`:

>>> with OutputCapture() as o:
...    print('  Bar! ')
>>> print(repr(o.captured))
'  Bar! \n'

If you need to explicitly check whether output went to ``stdout`` or ``stderr``,
`separate` mode can be used:

.. code-block:: python

  from testfixtures import OutputCapture
  import sys

  with OutputCapture(separate=True) as output:
      print("Hello!")
      print("Something bad happened!", file=sys.stderr)

  output.compare(
      stdout="Hello!",
      stderr="Something bad happened!",
  )

Finally, you may sometimes want to disable an :class:`OutputCapture`
without removing it from your code. This often happens when you want
to insert a :any:`breakpoint` call while an :class:`OutputCapture` is active;
if it remains enabled, all debugger output will be captured making the
debugger very difficult to use!

To deal with this problem, the :class:`OutputCapture` may be disabled
and then re-enabled as follows:

>>> with OutputCapture() as o:
...    print('Foo')
...    o.disable()
...    print('Bar')
...    o.enable()
...    print('Baz')
Bar
>>> print(o.captured)
Foo
Baz
<BLANKLINE>

.. note::

  Some debuggers, notably :mod:`pdb`, do interesting things with streams
  such that calling :meth:`~OutputCapture.disable` from within the debugger
  will have no effect. A good fallback is to type the following, which will
  almost always restore output to where you want it:

  .. code-block:: python

    import sys; sys.stdout=sys.__stdout__