pytest 測試輸出和結(jié)果-捕獲標(biāo)準(zhǔn)輸出/標(biāo)準(zhǔn)錯(cuò)誤輸出

2022-03-29 17:25 更新

默認(rèn)標(biāo)準(zhǔn)輸出/標(biāo)準(zhǔn)錯(cuò)誤/標(biāo)準(zhǔn)輸入捕獲行為

在測試執(zhí)行期間,任何發(fā)送到 ?stdout和 ?stderr的輸出都會(huì)被捕獲。 如果測試或設(shè)置方法失敗,其捕獲的輸出通常會(huì)與失敗回溯一起顯示。此行為可以通過 ?--show-capture? 命令行選項(xiàng)進(jìn)行配置)

此外,?stdin設(shè)置為?null?對象,嘗試讀取它時(shí)會(huì)失敗,因?yàn)樵谶\(yùn)行自動(dòng)化測試時(shí)很少需要等待交互式輸入。

默認(rèn)情況下,捕獲是通過攔截對低級文件描述符的寫入來完成的。 這允許捕獲簡單打印語句的輸出以及測試啟動(dòng)的子進(jìn)程的輸出。

設(shè)置捕獲方法或禁用捕獲

pytest 可以通過三種方式執(zhí)行捕獲:

  • ?fd?(文件描述符)級別捕獲(默認(rèn)):將捕獲到操作系統(tǒng)文件描述符 1 和 2 的所有寫入。
  • ?sys ?級別捕獲:僅會(huì)捕獲對 Python 文件 ?sys.stdout? 和 ?sys.stderr? 的寫入。 不捕獲對文件描述符的寫入。
  • ?tee-sys? 捕獲:Python 寫入 ?sys.stdout? 和 ?sys.stderr? 將被捕獲,但是寫入也將傳遞到實(shí)際的 ?sys.stdout? 和 ?sys.stderr?。 這允許輸出實(shí)時(shí)打印并捕獲以供插件使用,例如 ?junitxml?(pytest 5.4 中的新功能)。

您可以從命令行影響輸出捕獲機(jī)制:

pytest -s                  # disable all capturing
pytest --capture=sys       # replace sys.stdout/stderr with in-mem files
pytest --capture=fd        # also point filedescriptors 1 and 2 to temp file
pytest --capture=tee-sys   # combines 'sys' and '-s', capturing sys.stdout/stderr
                           # and passing it along to the actual sys.stdout/stderr

使用打印語句進(jìn)行調(diào)試

默認(rèn)捕獲 ?stdout?/?stderr輸出的一個(gè)主要好處是您可以使用打印語句進(jìn)行調(diào)試:

# content of test_module.py


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


def test_func1():
    assert True


def test_func2():
    assert False

運(yùn)行此模塊將準(zhǔn)確顯示失敗函數(shù)的輸出并隱藏另一個(gè):

$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items

test_module.py .F                                                    [100%]

================================= FAILURES =================================
________________________________ test_func2 ________________________________

    def test_func2():
>       assert False
E       assert False

test_module.py:12: AssertionError
-------------------------- Captured stdout setup ---------------------------
setting up <function test_func2 at 0xdeadbeef0001>
========================= short test summary info ==========================
FAILED test_module.py::test_func2 - assert False
======================= 1 failed, 1 passed in 0.12s ========================

從測試函數(shù)訪問捕獲的輸出

?capsys?、?capsysbinary?、?capfd?和?capfbinary fixture?允許訪問在測試執(zhí)行期間創(chuàng)建的?stdout?/?stderr?輸出。下面是一個(gè)測試函數(shù)的例子,它執(zhí)行一些輸出相關(guān)的檢查:

def test_myoutput(capsys):  # or use "capfd" for fd-level
    print("hello")
    sys.stderr.write("world\n")
    captured = capsys.readouterr()
    assert captured.out == "hello\n"
    assert captured.err == "world\n"
    print("next")
    captured = capsys.readouterr()
    assert captured.out == "next\n"

?readouterr()?調(diào)用快照到目前為止的輸出—并將繼續(xù)捕獲。測試函數(shù)完成后,將恢復(fù)原來的流。以這種方式使用?capsys?將您的測試從必須設(shè)置/重置輸出流的工作中解放出來,并且還可以很好地與pytest自己的每次測試捕獲進(jìn)行交互。

如果你想在文件描述符級別捕獲,你可以使用?capfd fixture?,它提供了完全相同的接口,但也允許捕獲庫或子進(jìn)程的輸出,這些子進(jìn)程直接寫入操作系統(tǒng)級別的輸出流(?FD1?和?FD2?)。

讀取器的返回值變成了一個(gè)有兩個(gè)屬性的命名元組,?out?和?err?。

如果被測試的代碼寫入非文本數(shù)據(jù),您可以使用?capsysbinary fixture?捕獲它,而不是從?readouterr?方法返回字節(jié)。

如果被測試的代碼寫入非文本數(shù)據(jù),您可以使用?capfbinary fixture?捕獲它,而不是從?readouterr?方法返回字節(jié)。?capfbinary fixture?在文件描述符級別上操作。

為了在測試中暫時(shí)禁用捕獲,?capsys?和?capfd?都有一個(gè)?disabled()?方法,它可以用作上下文管理器,在?with?塊中禁用捕獲:

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")


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號