目錄python
在測試執行期間,任何標準輸出和標準錯誤輸出都將會被捕獲;若是測試失敗或者發生異常,異常信息的堆棧也將一同顯示,你能夠經過--show-capture
命令行選項來自定義這些行爲;git
--show-capture
的配置項能夠爲:no,stdout,stderr,log,all
,默認是all
;github
另外,標準輸入被設置爲一個"null"
對象。由於在自動化測試中,不多須要使用到交互輸入的場景;緩存
實際上,當咱們想要使用標準輸入時,會獲得一個錯誤:
OSError: reading from stdin while output is captured
;bash
一般狀況下,捕獲行爲是經過攔截對低級別文件描述符的寫入操做來實現的。這就使得咱們能夠捕獲簡單的print()
語句以及測試中子程序的輸出行爲;函數
pytest
有兩種捕獲行爲,能夠經過--capture
命令行選項來指定;測試
全部向操做系統的文件描述符1(標準輸入)和2(標準錯誤輸入)的寫入行爲都會被捕獲,這個也是pytest
的默認捕獲行爲,也能夠經過--capture=fd
來指定;ui
文件描述符是與當前進程打開的文件相對應的小整數。例如,標準輸入的文件描述符一般是0,標準輸出的是1,標準錯誤的是2,以後被進程打開的文件的描述符依次指定爲三、四、5等。操作系統
sys
級別的捕獲行爲只有向Python
的sys.stdout
和sys.stderr
的寫入行爲會被捕獲,不執行對文件描述符的寫入的捕獲,經過--capture=sys
來指定;命令行
經過--capture=no
能夠去使能pytest
的捕獲行爲;
也能夠經過-s
命令行選項實現相同的效果,它只是--capture=no
的一個快捷方式,本質上是同樣的;
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
會把失敗的用例信息精確的打印出來,而且會忽略其餘的用例;
咱們能夠經過capsys
、capsysbinary
、capfd
和capfdbinary 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()
方法會返回一個命名元組(包含out
和err
屬性),表示到目前爲止全部的標準輸出和標準錯誤輸出,而後重置緩存區;
若是你想訪問文件描述符級別的測試輸出,可使用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"