七、pytest -- 捕獲標準輸出和標準錯誤輸出

1. 標準輸出/標準錯誤輸出/標準輸入的默認捕獲行爲

在測試執行期間,任何標準輸出和標準錯誤輸出都將會被捕獲;若是測試失敗或者發生異常,異常信息的堆棧也將一同顯示,你能夠經過--show-capture命令行選項來自定義這些行爲;git

--show-capture的配置項能夠爲:no,stdout,stderr,log,all,默認是allgithub

另外,標準輸入被設置爲一個"null"對象。由於在自動化測試中,不多須要使用到交互輸入的場景;緩存

實際上,當咱們想要使用標準輸入時,會獲得一個錯誤:OSError: reading from stdin while output is capturedbash

一般狀況下,捕獲行爲是經過攔截對低級別文件描述符的寫入操做來實現的。這就使得咱們能夠捕獲簡單的print()語句以及測試中子程序的輸出行爲;函數

2. 修改和去使能捕獲行爲

pytest有兩種捕獲行爲,能夠經過--capture命令行選項來指定;測試

2.1. 文件描述符級別的捕獲行爲(默認)

全部向操做系統的文件描述符1(標準輸入)和2(標準錯誤輸入)的寫入行爲都會被捕獲,這個也是pytest的默認捕獲行爲,也能夠經過--capture=fd來指定;ui

文件描述符是與當前進程打開的文件相對應的小整數。例如,標準輸入的文件描述符一般是0,標準輸出的是1,標準錯誤的是2,以後被進程打開的文件的描述符依次指定爲三、四、5等。操作系統

2.2. sys級別的捕獲行爲

只有向Pythonsys.stdoutsys.stderr的寫入行爲會被捕獲,不執行對文件描述符的寫入的捕獲,經過--capture=sys來指定;命令行

2.3. 去使能捕獲行爲

經過--capture=no能夠去使能pytest的捕獲行爲;

也能夠經過-s命令行選項實現相同的效果,它只是--capture=no的一個快捷方式,本質上是同樣的;

3. 使用print()函數調試用例

默認的捕獲行爲帶來的一個主要的好處是,就是可使用print()函數幫助調試用例;

咱們來看下面這個例子:

# src/chapter-7/test_module.py

def setup_function(function):
    print("setting up", function)


def test_func1():
    assert True


def test_func2():
    assert False

setup_function(function)函數會在每一個測試用例開始以前執行,作一些初始化的操做;

如今,咱們來執行這個模塊:

λ pipenv run pytest -q src/chapter-7/test_module.py
.F                                                      [100%] 
========================== FAILURES ========================== 
_________________________ test_func2 _________________________

    def test_func2():
>       assert False
E       assert False

src\chapter-7\test_module.py:32: AssertionError
------------------- Captured stdout setup -------------------- 
setting up <function test_func2 at 0x000001F35E76C158>
1 failed, 1 passed in 0.05s

能夠看到,pytest會把失敗的用例信息精確的打印出來,而且會忽略其餘的用例;

4. 在測試用例中訪問捕獲到的信息

咱們能夠經過capsyscapsysbinarycapfdcapfdbinary fixtures來訪問測試執行過程當中產生的輸出信息;

下面這個例子用於檢查測試中的輸出信息:

# src/chapter-7/test_output.py

import sys


def test_output(capsys):
    print('hello')
    print('world', file=sys.stderr, end='&')  # 標準錯誤輸出,修改結束符
    captured = capsys.readouterr()
    assert captured.out == 'hello\n'  # print() 默認的結束符是換行符
    assert captured.err == 'world&'
    print('next')
    captured = capsys.readouterr()
    assert captured.out == 'next\n'

readouterr()方法會返回一個命名元組(包含outerr屬性),表示到目前爲止全部的標準輸出和標準錯誤輸出,而後重置緩存區

若是你想訪問文件描述符級別的測試輸出,可使用capfd fixture,它提供了徹底相同的接口;

若是想訪問的是非文本型的數據,可使用capsysbinary fixture,它的readouterr()方法返回的是字節流,參考下面的例子:

# src/chapter-7/test_output.py

def test_binary_output(capsysbinary):
    print('hello')
    captured = capsysbinary.readouterr()
    assert captured.out == b'hello\n'

若是你想臨時的去使能捕獲行爲,可使用capsys.disabled()方法,它做爲一個上下文管理器來使用,能夠禁止with做用域中的捕獲行爲,參考下面的例子:

# src/chapter-7/test_output.py

def test_disabling_capturing(capsys):
    print("hello")
    with capsys.disabled():
        print("world")
    captured = capsys.readouterr()
    assert captured.out == "hello\n"

GitHub倉庫地址:https://github.com/luizyao/pytest-chinese-doc

相關文章
相關標籤/搜索