Pytest----如何捕获标准输出和标准错误输出

简介: Pytest----如何捕获标准输出和标准错误输出

一、设置标准输出标准错误输出的模式

pytest捕获标准输出标准错误输出的模式主要有以下几种

  • pytest :和pytest --capture=fd 模式是一样的,默认的就是pytest --capture=fd 模式
  • pytest -s :打开实时输出,关闭Capture Log输出,
  • pytest --capture=sys :打开实时输出,Captrue Log只捕获sys.out,sys.err
  • pytest --capture=fd :关闭实时输出,Captrue Log捕获所有的标准输出
  • pytest --capture=tee-sys :pytest -s 和 pytest --capture=sys的结合,即打开实时输出,同时Captrue Log只捕获sys.out,sys.err

test_demo.py代码如下:

import sys
import os

def test_demo():
    print("in test_demo...")
    os.system("dir")
    sys.stdout.write("hello\n")
    assert 1==2

(1)使用pytest命令执行,此时关闭实时输出,Capture Log捕获所有的标准输出

如下,可以看到Capture Log既有sys.out的输出,也有执行系统命令的输出(执行系统命令的输出不是sys.out,而是文件描述符1)

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py F                                                           [100%]

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

    def test_demo():
        print("in test_demo...")
        os.system("dir")
        sys.stdout.write("hello\n")
>       assert 1==2
E       assert 1 == 2

test_demo.py:8: AssertionError
---------------------------- Captured stdout call -----------------------------
in test_demo...
 Volume in drive D is work
 Volume Serial Number is 84B0-F6B7

 Directory of D:\src\blog\tests

2021/12/27  09:38    <DIR>          .
2021/12/27  09:38    <DIR>          ..
2021/12/24  17:03    <DIR>          .pytest_cache
2021/12/27  09:32                16 1
2021/12/23  15:31               168 conftest.py
2021/12/22  17:13               300 pytest.ini
2021/12/16  09:21             1,797 red_blue_ball_ticket.py
2021/12/27  09:38               143 test_demo.py
2021/12/24  15:38                 0 __init__.py
2021/12/27  09:38    <DIR>          __pycache__
               6 File(s)          2,424 bytes
               4 Dir(s)  165,265,436,672 bytes free
hello
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - assert 1 == 2
============================== 1 failed in 0.06s ==============================

(2)使用pytest -s 命令,此时打开实时输出,关闭Capture Log输出

如下,只有实时输出,没有Captured stdout call内容

$ pytest -s
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py  Volume in drive D is work
 Volume Serial Number is 84B0-F6B7

 Directory of D:\src\blog\tests

2021/12/27  09:38    <DIR>          .
2021/12/27  09:38    <DIR>          ..
2021/12/24  17:03    <DIR>          .pytest_cache
2021/12/27  09:32                16 1
2021/12/23  15:31               168 conftest.py
2021/12/22  17:13               300 pytest.ini
2021/12/16  09:21             1,797 red_blue_ball_ticket.py
2021/12/27  09:38               143 test_demo.py
2021/12/24  15:38                 0 __init__.py
2021/12/27  09:38    <DIR>          __pycache__
               6 File(s)          2,424 bytes
               4 Dir(s)  165,265,436,672 bytes free
in test_demo...
hello
F

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

    def test_demo():
        print("in test_demo...")
        os.system("dir")
        sys.stdout.write("hello\n")
>       assert 1==2
E       assert 1 == 2

test_demo.py:8: AssertionError
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - assert 1 == 2
============================== 1 failed in 0.06s ==============================

(3)使用pytest --capture=sys 命令时打开实时输出,Capture Log只输出sys.out的内容

如下,Capture Log中只有sys.out的内容,没有执行系统命令的输出

$ pytest --capture=sys
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py  Volume in drive D is work
 Volume Serial Number is 84B0-F6B7

 Directory of D:\src\blog\tests

2021/12/27  09:38    <DIR>          .
2021/12/27  09:38    <DIR>          ..
2021/12/24  17:03    <DIR>          .pytest_cache
2021/12/27  09:32                16 1
2021/12/23  15:31               168 conftest.py
2021/12/22  17:13               300 pytest.ini
2021/12/16  09:21             1,797 red_blue_ball_ticket.py
2021/12/27  09:38               143 test_demo.py
2021/12/24  15:38                 0 __init__.py
2021/12/27  09:38    <DIR>          __pycache__
               6 File(s)          2,424 bytes
               4 Dir(s)  165,265,432,576 bytes free
F                                                           [100%]

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

    def test_demo():
        print("in test_demo...")
        os.system("dir")
        sys.stdout.write("hello\n")
>       assert 1==2
E       assert 1 == 2

test_demo.py:8: AssertionError
---------------------------- Captured stdout call -----------------------------
in test_demo...
hello
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - assert 1 == 2
============================== 1 failed in 0.06s ==============================

(4)使用 pytest --capture=fd 命令关闭实时输出,Captrue Log捕获所有的标准输出

$ pytest --capture=fd
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py F                                                           [100%]

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

    def test_demo():
        print("in test_demo...")
        os.system("dir")
        sys.stdout.write("hello\n")
>       assert 1==2
E       assert 1 == 2

test_demo.py:8: AssertionError
---------------------------- Captured stdout call -----------------------------
in test_demo...
 Volume in drive D is work
 Volume Serial Number is 84B0-F6B7

 Directory of D:\src\blog\tests

2021/12/27  09:38    <DIR>          .
2021/12/27  09:38    <DIR>          ..
2021/12/24  17:03    <DIR>          .pytest_cache
2021/12/27  09:32                16 1
2021/12/23  15:31               168 conftest.py
2021/12/22  17:13               300 pytest.ini
2021/12/16  09:21             1,797 red_blue_ball_ticket.py
2021/12/27  09:38               143 test_demo.py
2021/12/24  15:38                 0 __init__.py
2021/12/27  09:38    <DIR>          __pycache__
               6 File(s)          2,424 bytes
               4 Dir(s)  165,265,432,576 bytes free
hello
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - assert 1 == 2
============================== 1 failed in 0.06s ==============================

(5)使用pytest --capture=tee-sys命令,相当于pytest -s 和 pytest --capture=sys的结合,即打开实时输出,同时Captrue Log只捕获sys.out,sys.err

$ pytest --capture=tee-sys
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py  Volume in drive D is work
 Volume Serial Number is 84B0-F6B7

 Directory of D:\src\blog\tests

2021/12/27  09:38    <DIR>          .
2021/12/27  09:38    <DIR>          ..
2021/12/24  17:03    <DIR>          .pytest_cache
2021/12/27  09:32                16 1
2021/12/23  15:31               168 conftest.py
2021/12/22  17:13               300 pytest.ini
2021/12/16  09:21             1,797 red_blue_ball_ticket.py
2021/12/27  09:38               143 test_demo.py
2021/12/24  15:38                 0 __init__.py
2021/12/27  09:38    <DIR>          __pycache__
               6 File(s)          2,424 bytes
               4 Dir(s)  165,265,428,480 bytes free
in test_demo...
hello
F                                                           [100%]

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

    def test_demo():
        print("in test_demo...")
        os.system("dir")
        sys.stdout.write("hello\n")
>       assert 1==2
E       assert 1 == 2

test_demo.py:8: AssertionError
---------------------------- Captured stdout call -----------------------------
in test_demo...
hello
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - assert 1 == 2
============================== 1 failed in 0.06s ==============================

二、在测试函数中捕获标准输出标砖错误输出

用于捕获标准输出有如下四个fixture:capsys, capsysbinary, capfd,和capfdbinary,capsys用于获取sys.out中的内容,当sys.out中的内容为二进制数据时使用capsysbinary,同样,capfd用于获取系统级标准输出,即文件描述符1和2,当数据为二进制时使用和capfdbinary

test_demo.py代码如下:

def test_demo(capsys):
    print("hello world")
    captured = capsys.readouterr()
    assert "hello world hahaha" in captured.out

执行结果如下,可以发现这里能将上面打印语句的内容捕获到,即"hello world\n",这里断言报错主要是通过报错信息查看真是额返回值

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py F                                                           [100%]

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

capsys = <_pytest.capture.CaptureFixture object at 0x00000226B8916D00>

    def test_demo(capsys):
        print("hello world")
        captured = capsys.readouterr()
>       assert "hello worldd" in captured.out
E       AssertionError: assert 'hello worldd' in 'hello world\n'
E        +  where 'hello world\n' = CaptureResult(out='hello world\n', err='').out

test_demo.py:5: AssertionError
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - AssertionError: assert 'hello worldd' in 'he...
============================== 1 failed in 0.05s ==============================

还可以设置对指定的内容关闭capture捕获,如下

test_demo.py代码如下,设置当打印hello python的时候关闭捕获

def test_demo(capsys):
    print("hello world")
    with capsys.disabled():
        print("hello python")
    print("hello C++")
    captured = capsys.readouterr()
    assert "hello world" in captured.out
    assert "hello C++" in captured.out
    assert "hello python" in captured.out

执行结果如下,可以发现,这里确实只捕获了hello world 和hello C++的打印

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py hello python
F                                                           [100%]

================================== FAILURES ===================================
__________________________________ test_demo __________________________________

capsys = <_pytest.capture.CaptureFixture object at 0x00000294FFB444C0>

    def test_demo(capsys):
        print("hello world")
        with capsys.disabled():
            print("hello python")
        print("hello C++")
        captured = capsys.readouterr()
        assert "hello world" in captured.out
        assert "hello C++" in captured.out
>       assert "hello python" in captured.out
E       AssertionError: assert 'hello python' in 'hello world\nhello C++\n'
E        +  where 'hello world\nhello C++\n' = CaptureResult(out='hello world\nhello C++\n', err='').out

test_demo.py:10: AssertionError
=========================== short test summary info ===========================
FAILED test_demo.py::test_demo - AssertionError: assert 'hello python' in 'he...
============================== 1 failed in 0.06s ==============================
目录
相关文章
|
2月前
输出当前文件执行代码
【10月更文挑战第11天】输出当前文件执行代码。
27 4
|
7月前
|
程序员
第四十二章 使用^%SYS.MONLBL检查例程性能 - 逐行分隔输出报告
第四十二章 使用^%SYS.MONLBL检查例程性能 - 逐行分隔输出报告
39 0
|
5月前
|
Unix Linux Python
`subprocess`模块允许你启动新的应用程序,连接到它们的输入/输出/错误管道,并获取它们的返回码。
`subprocess`模块允许你启动新的应用程序,连接到它们的输入/输出/错误管道,并获取它们的返回码。
|
5月前
|
Unix Linux Python
`subprocess`模块是Python中用于生成新进程、连接到它们的输入/输出/错误管道,并获取它们的返回(退出)代码的模块。
`subprocess`模块是Python中用于生成新进程、连接到它们的输入/输出/错误管道,并获取它们的返回(退出)代码的模块。
|
7月前
|
监控
第四十一章 使用^%SYS.MONLBL检查例程性能 - 逐行监控报告示例
第四十一章 使用^%SYS.MONLBL检查例程性能 - 逐行监控报告示例
49 0
|
7月前
|
Unix Shell Linux
第八章 Shell标准输入、输出和错误
第八章 Shell标准输入、输出和错误
|
JSON 前端开发 数据格式
ThinkPHP6.0日志没有输出到文件而是直接输出到了输出流
ThinkPHP6.0日志没有输出到文件而是直接输出到了输出流
189 0
|
Python
Python输出异常信息(行号)
Python输出异常信息(行号)
318 0
Python-技术篇-使用logging模块打印详细报错日志,获取报错信息位置行数方法
Python-技术篇-使用logging模块打印详细报错日志,获取报错信息位置行数方法
1185 0
Python-技术篇-使用logging模块打印详细报错日志,获取报错信息位置行数方法