[英]Pytest capture stdout of a certain test
有沒有辦法只為特定測試獲取Captured stdout call
而不會使測試失敗?
假設我有 10 個測試,外加一個 test_summary。 test_summary 實際上只是打印測試的某種摘要/統計數據,但為了讓我獲得該輸出/打印輸出,我目前必須故意使該測試失敗。 當然這個 test_summary 最后使用 pytest-ordering 運行。 但是有沒有更好的方法可以在不通過測試的情況下獲得結果呢? 或者它不應該在測試中,而是在 conftest.py 或其他東西中? 請就最佳實踐以及我如何獲得此摘要/結果提出建議(基本上是我編寫的特定腳本的打印輸出)
首先,回答你的確切問題:
有沒有辦法只為特定測試獲取
Captured stdout call
而不會使測試失敗?
您可以添加一個自定義部分,模仿Captured stdout call
並在測試成功時打印。 在每個測試中捕獲的 output 存儲在相關的TestReport
object 中,並通過report.capstdout
訪問。 示例實現:將以下代碼添加到項目或測試根目錄中的conftest.py
中:
import os
def pytest_terminal_summary(terminalreporter, exitstatus, config):
# on failures, don't add "Captured stdout call" as pytest does that already
# otherwise, the section "Captured stdout call" will be added twice
if exitstatus > 0:
return
# get all reports
reports = terminalreporter.getreports('')
# combine captured stdout of reports for tests named `<smth>::test_summary`
content = os.linesep.join(
report.capstdout for report in reports
if report.capstdout and report.nodeid.endswith("test_summary")
)
# add custom section that mimics pytest's one
if content:
terminalreporter.ensure_newline()
terminalreporter.section(
'Captured stdout call',
sep='-',
blue=True,
bold=True,
)
terminalreporter.line(content)
這將添加一個自定義部分Captured stdout call
,該調用將只打印為 ID 以 test_summary 結尾的測試捕獲的test_summary
(如果您有多個名為test_summary
的測試函數,請擴展檢查)。 為了區分這兩個部分,自定義部分有一個藍色的 header; 如果您希望它與原始顏色匹配,請通過blue=True
arg 刪除顏色設置。
現在,解決您的實際問題:
test_summary
實際上只是打印測試的某種摘要/統計信息
使用自定義報告測試對我來說很像是一種變通方法; 為什么不在測試中收集數據並在之后添加一個自定義部分來打印該數據? 要收集數據,您可以使用record_property
fixture:
def test_foo(record_property):
# records a key-value pair
record_property("hello", "world")
def test_bar(record_property):
record_property("spam", "eggs")
收集和 output 記錄的自定義屬性,稍微改變上面的 hookimpl。 通過report.user_properties
record_property
:
import os
def pytest_terminal_summary(terminalreporter, exitstatus, config):
reports = terminalreporter.getreports('')
content = os.linesep.join(
f'{key}: {value}' for report in reports
for key, value in report.user_properties
)
if content:
terminalreporter.ensure_newline()
terminalreporter.section(
'My custom summary',
sep='-',
blue=True,
bold=True
)
terminalreporter.line(content)
運行上述測試現在產生:
$ pytest test_spam.py
=============================== test session starts ================================
platform linux -- Python 3.9.0, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
rootdir: /home/oleg.hoefling/projects/private/stackoverflow/so-64812992
plugins: metadata-1.10.0, json-report-1.2.4, cov-2.10.1, forked-1.3.0, xdist-2.1.0
collected 2 items
test_spam.py .. [100%]
-------------------------------- My custom summary ---------------------------------
hello: world
spam: eggs
================================ 2 passed in 0.01s =================================
您可以使用標准的 pytest 終端記者。
def test_a(request):
reporter = request.config.pluginmanager.getplugin("terminalreporter")
reporter.write_line("Hello", yellow=True)
reporter.write_line("World", red=True)
reporter 是我記得的所有 pytest 版本的標准插件。 不幸的是,它沒有記錄在案,而 API 非常穩定。
你可以在pytest的github上找到TerminalReporter
class: https://github.com/pytest-dev/pytest/blob/master/src/_pytest/terminal.py
對您最有用的方法可能是ensure_line()
、 write()
、 flush()
和絕對冠軍 -- write_line()
,它們可以完成所有工作。
可用的 styles 可以在https://github.com/pytest-dev/pytest/blob/master/src/_pytest/_io/terminalwriter.py找到
_esctable = dict(
black=30,
red=31,
green=32,
yellow=33,
blue=34,
purple=35,
cyan=36,
white=37,
Black=40,
Red=41,
Green=42,
Yellow=43,
Blue=44,
Purple=45,
Cyan=46,
White=47,
bold=1,
light=2,
blink=5,
invert=7,
)
小寫 styles 表示前景,大寫表示背景。
例如,綠色文本上的黃色應打印為
reporter.write_line("Text", yellow=True, Green=True)
我希望這個說明能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.