![](/img/trans.png)
[英]How can I access the overall test result of a pytest test run during runtime?
[英]How can I see normal print output created during pytest run?
有時我只想在我的代碼中插入一些打印語句,然后看看我在執行它時會打印出什么。 我常用的“鍛煉”方法是使用現有的 pytest 測試。 但是當我運行這些時,我似乎看不到任何標准輸出(至少在我的 IDE PyCharm 中)。
有沒有一種簡單的方法可以在 pytest 運行期間查看標准輸出?
-s
開關禁用每次測試捕獲(僅當測試失敗時)。
-s
相當於--capture=no
。
pytest 從單個測試中捕獲標准輸出並僅在某些條件下顯示它們,以及默認情況下打印的測試摘要。
可以使用“-r”選項顯示額外的摘要信息:
pytest -rP
顯示已通過測試的捕獲輸出。
pytest -rx
顯示失敗測試的捕獲輸出(默認行為)。
輸出的格式使用 -r 比使用 -s 更漂亮。
有什么方法可以打印到控制台並捕獲輸出以便它顯示在 junit 報告中?
在 UNIX 中,這通常稱為teeing 。 理想情況下, py.test 的默認設置是發球而不是捕獲。 非理想情況下,py.test 和任何現有的第三方 py.test 插件(我知道,無論如何)都不支持 teeing——盡管 Python 微不足道地支持 teeing out-of-the-box 。
Monkey-patching py.test 做任何不受支持的事情都是不平凡的。 為什么? 因為:
_pytest
包后面。 在不知道自己在做什么的情況下嘗試這樣做通常會導致公共pytest
包在運行時引發晦澀的異常。 非常感謝,py.test。 真正強大的架構,你在那里。_pytest
API 進行猴子修補,您也必須在運行由外部py.test
命令運行的公共pytest
包之前這樣做。 您不能在插件中執行此操作(例如,測試套件中的頂級conftest
模塊)。 當 py.test 懶惰地開始動態導入你的插件時,任何你想要猴子補丁的 py.test 類早就被實例化了——你無法訪問那個實例。 這意味着,如果您希望有意義地應用猴子補丁,則不能再安全地運行外部py.test
命令。 相反,您必須使用自定義 setuptools test
命令來包裝該命令的運行,該命令(按順序):
_pytest
API。pytest.main()
函數來運行py.test
命令。 這個答案猴子補丁 py.test 的-s
和--capture=no
選項來捕獲標准錯誤而不是標准輸出。 默認情況下,這些選項既不捕獲標准錯誤也不捕獲標准輸出。 當然,這並不完全是開球。 但每一次偉大的旅程都始於一個乏味的前傳,每個人都會在五年內忘記。
為什么要這樣做? 我現在告訴你。 我的 py.test 驅動的測試套件包含緩慢的功能測試。 顯示這些測試的標准輸出是有幫助和令人放心的,當另一個長時間運行的功能測試連續數周都沒有做任何事情時,可以防止leycec到達killall -9 py.test
。 但是,顯示這些測試的標准錯誤會阻止 py.test 報告測試失敗的異常回溯。 這是完全沒有幫助的。 因此,我們強制 py.test 捕獲 stderr 而不是stdout。
在我們開始之前,這個答案假設您已經有一個調用 py.test 的自定義 setuptools test
命令。 如果您不這樣做,請參閱 py.test 編寫良好的良好實踐頁面的手動集成小節。
不要安裝pytest-runner ,第三方 setuptools 插件提供自定義 setuptools test
命令也調用 py.test。 如果 pytest-runner 已經安裝,您可能需要卸載該 pip3 包,然后采用上面鏈接的手動方法。
假設您按照上面突出顯示的手動集成中的說明進行操作,您的代碼庫現在應該包含一個PyTest.run_tests()
方法。 將此方法修改為類似於:
class PyTest(TestCommand):
.
.
.
def run_tests(self):
# Import the public "pytest" package *BEFORE* the private "_pytest"
# package. While importation order is typically ignorable, imports can
# technically have side effects. Tragicomically, that is the case here.
# Importing the public "pytest" package establishes runtime
# configuration required by submodules of the private "_pytest" package.
# The former *MUST* always be imported before the latter. Failing to do
# so raises obtuse exceptions at runtime... which is bad.
import pytest
from _pytest.capture import CaptureManager, FDCapture, MultiCapture
# If the private method to be monkey-patched no longer exists, py.test
# is either broken or unsupported. In either case, raise an exception.
if not hasattr(CaptureManager, '_getcapture'):
from distutils.errors import DistutilsClassError
raise DistutilsClassError(
'Class "pytest.capture.CaptureManager" method _getcapture() '
'not found. The current version of py.test is either '
'broken (unlikely) or unsupported (likely).'
)
# Old method to be monkey-patched.
_getcapture_old = CaptureManager._getcapture
# New method applying this monkey-patch. Note the use of:
#
# * "out=False", *NOT* capturing stdout.
# * "err=True", capturing stderr.
def _getcapture_new(self, method):
if method == "no":
return MultiCapture(
out=False, err=True, in_=False, Capture=FDCapture)
else:
return _getcapture_old(self, method)
# Replace the old with the new method.
CaptureManager._getcapture = _getcapture_new
# Run py.test with all passed arguments.
errno = pytest.main(self.pytest_args)
sys.exit(errno)
要啟用此猴子補丁,請按如下方式運行 py.test:
python setup.py test -a "-s"
現在將捕獲 Stderr 但不是stdout。 漂亮!
將上面的猴子補丁擴展到 tee stdout 和 stderr 留給讀者作為練習,並有大量空閑時間。
運行測試時使用-s
選項。 運行測試時, exampletest.py
中的所有打印語句都將打印在控制台上。
py.test exampletest.py -s
根據pytest 文檔,pytest 版本 3 可以在測試中臨時禁用捕獲:
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')
最近添加了pytest --capture=tee-sys
( v5.4.0 )。 您可以捕獲並查看 stdout/err 上的輸出。
嘗試pytest -s -v test_login.py
在控制台中獲取更多信息。
-v
這是一個簡短的--verbose
-s
表示“禁用所有捕獲”
您還可以通過在項目根目錄中的pytest.ini
或tox.ini
中設置以下內容來啟用實時日志記錄。
[pytest]
log_cli = True
或者直接在cli上指定
pytest -o log_cli=True
pytest test_name.py -v -s
簡單的!
我建議使用 -h 命令。 可能會使用一些非常有趣的命令。 但是,對於這種特殊情況: -s快捷方式為 --capture=no。 足夠的
pytest <test_file.py> -s
如果您使用的是 PyCharm IDE,那么您可以使用運行工具欄運行單個測試或所有測試。 運行工具窗口顯示應用程序生成的輸出,您可以在其中看到所有打印語句作為測試輸出的一部分。
如果您使用logging
,除了-s
用於通用標准輸出之外,您還需要指定打開日志輸出。 基於pytest 測試中的日志記錄,我正在使用:
pytest --log-cli-level=DEBUG -s my_directory/
如果有人想從帶有輸出的代碼運行測試:
if __name__ == '__main__':
pytest.main(['--capture=no'])
capsys、capsysbinary、capfd 和 capfdbinary 夾具允許訪問在測試執行期間創建的 stdout/stderr 輸出。 這是一個執行一些輸出相關檢查的示例測試函數:
def test_print_something_even_if_the_test_pass(self, capsys):
text_to_be_printed = "Print me when the test pass."
print(text_to_be_printed)
p_t = capsys.readouterr()
sys.stdout.write(p_t.out)
# the two rows above will print the text even if the test pass.
結果如下:
test_print_something_even_if_the_test_pass PASSED [100%]當測試通過時打印我。
其他答案不起作用。 查看捕獲的輸出的唯一方法是使用以下標志:
pytest - 顯示全部捕獲
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.