使用py.tests capys捕获stderr

Bjö*_*lex 5 python pytest

我试图使用py.tests capsysfixture来捕获标准错误流.但是,这似乎不像宣传的那样有效.鉴于这个简单的测试:

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'
Run Code Online (Sandbox Code Playgroud)

在Python 3.4.3上使用py.test 2.7.0运行时产生以下输出:

    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
Run Code Online (Sandbox Code Playgroud)

奇怪的是py.test报告错误流的正确内容,但capsys似乎没有捕获它.难道我做错了什么?这是一个错误吗?

Bjö*_*lex 7

capsys灯具的工作原理是替换sys.stderr与它自己的虚拟文件对象.在上面给出的代码中,这种替换只 测试导入才会发生,这sys.stderr使得它无用.要解决此问题,可以sys.stderr在测试中导入.

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'
Run Code Online (Sandbox Code Playgroud)

unittest.mock模块文档中更好地描述了此问题.

  • 只是为了添加答案,替代方法是`import sys`并在代码中使用`sys.stderr`. (3认同)