小门板儿

Menu

pytest:捕获 STDOUT/STDERR 输出

一、默认的 stdout/stderr/stdin 捕捉行为

在测试执行的过程中,很多输出被 stdout 和 stderr 捕获。当一个测试或者setup方法失败的时候,相关的输出经常会与错误跟踪( failure traceback)一起显示。(这个行为可以被命令行中 --show-capture 选项配置)。

另外,如果从stdin中读取失败了,它将会被设置为“null”,因为在自动化测试中,我们几乎不可能等待一个交互式的输入。

二、设置捕捉方法或禁用捕捉

在pytest中有三种执行捕获的方式:

你可以通过命令行来修改输出的机制:

pytest -s # 禁用所有的抓取
pytest --capture=sys # 使用python文件中的 sys.stdout/stderr 替换原有的标准输出
pytest --capture=fd # 也输出标准输出和标准错误输出
pytest --capture=tee-sys # 结合了 'sys' 和 '-s',抓取 sys.stdout/stderr 然后传递给真实的标准输出

三、使用print来调试

def setup_func(function):
    print("setting up", function)
​
def test_func1():
    assert True
​
def test_func2():
    assert False

运行此模块将精确显示失败函数的输出

D:\pytest\learn01\a>pytest -s -v test_std.py
========================================================================================== test session starts ===========================================================================================
platform win32 -- Python 3.7.3, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- d:\python3.7\python\python3.exe
cachedir: .pytest_cache
rootdir: D:\pytest\learn01, configfile: pytest.ini
collected 2 items                                                                                                                                                                                         
test_std.py::test_func1 PASSED
test_std.py::test_func2 FAILED
​
=========================================== FAILURES ===========================================
___________________________________________ test_func2 ___________________________________________
    def test_func2():
>       assert False
E       assert False
​
test_std.py:8: AssertionError
============================================= short test summary info =============================================
FAILED test_std.py::test_func2 - assert False
====================================== 1 failed, 1 passed in 0.16s =======================================

四、在测试方法中访问标准输出

capsys, capsysbinary, capfd, 和capfdbinary 四个夹具允许我们在测试执行的时候访问 stdout/stderr 的输出。下面是一些执行输出检查的例子:

def test_output(capsys):
    print("hello world")
    sys.stderr.write('hello erro')
    output=capsys.readouterr()
    assert output.out == "hello world\n"
    assert output.err == "hello erro"
    print('next')
    output = capsys.readouterr()
    assert output.out=='next\n'

readouterr() 获取了标准输出当前状态的快照,并且会继续捕获。在测试函数完成之后,原始的输出流会被恢复。使用 capsys 这种方法使得我们不需要关注获取输出流和在测试之后重置输出流,同时与pytest自身的捕获机制兼容良好。 如果你想在文件描述符的层面进行捕获,你可以使用 capfd夹具,这个夹具的使用方法与上面介绍的相同,同时也允许从库中或子进程中抓取那些直接写入操作系统的输出流。 readouterr的返回值改变为两个属性的元组,out和err。 如果测试中写入的数据不是文本类型(non-textual)的,你也可以使用capsysbinary来捕获二进制数据,readouterr方法返回一个bytes。 如果测试中写入的数据不是文本类型(non-textual)的,你也可以使用capfdbinary来捕获二进制数据,readouterr方法返回一个bytes。capfdbinary夹具是作用在文件描述符层面。

为了在一个测试中暂时的禁用捕获器,capsys和capfd都拥有一个 disabled() 方法,我们可以使用一个上下文管理器去在某一块中禁用捕

def test_disabling_capturing(capsys):
    print("this output is captured")
    with capsys.disabled():
        print("output not captured, going directly to sys.stdout")
    print("this output is also captured")
D:\pytest\learn01\a>pytest  test_std.py
=========================== test session starts ============================
platform win32 -- Python 3.7.3, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: D:\pytest\learn01, configfile: pytest.ini
collected 1 item                                                                                                                                                                                          
test_std.py output not captured, going directly to sys.stdout
.                                                                                                                                                                                       [100%]
=================================== 1 passed in 0.09s ====================================

参考文献:https://www.osgeo.cn/pytest/capture.html

— 于 共写了3484个字
— 标签:

评论已关闭。