Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing stderr using py.tests capsys

Tags:

python

pytest

I am trying to use py.tests capsys fixture to capture the standard error stream. However, this doesn't seem to work as advertised. Given this simple test:

from sys import stderr


def test_capsys(capsys):
    print('foo')
    print('bar', file=stderr)

    out, err = capsys.readouterr()
    assert out == 'foo\n'
    assert err == 'bar\n'

Produces the following output when run with py.test 2.7.0 on Python 3.4.3:

    def test_capsys(capsys):
        print('foo')
        print('bar', file=stderr)

        out, err = capsys.readouterr()
        assert out == 'foo\n'
>       assert err == 'bar\n'
E       assert '' == 'bar\n'
E         + bar

test_capsys.py:10: AssertionError
----------------------------- Captured stderr call -----------------------------
bar

The strange thing is that py.test reports the correct contents for the error stream, but capsys doesn't seem to capture it. Am I doing something wrong? Is this a bug?

like image 927
Björn Pollex Avatar asked Apr 10 '15 17:04

Björn Pollex


1 Answers

The capsys fixture works by replacing sys.stderr with it's own virtual file object. In the code given above, this replacement happens only after the test imports sys.stderr, making it useless. To fix this problem, one can import sys.stderr inside the test.

def test_capsys(capsys):
    from sys import stderr

    print('foo')
    print('bar', file=stderr)

    out, err = capsys.readouterr()
    assert out == 'foo\n'
    assert err == 'bar\n'

This problem is better described in the documentation of the unittest.mock module.

like image 74
Björn Pollex Avatar answered Oct 13 '22 17:10

Björn Pollex