如何管理日誌記錄¶
pytest 自動捕獲日誌級別為 WARNING
或更高級別的日誌消息,並以與捕獲的 stdout 和 stderr 相同的方式在每個失敗測試的單獨部分中顯示它們。
無選項運行
pytest
像這樣顯示失敗的測試
----------------------- Captured stdlog call ----------------------
test_reporting.py 26 WARNING text going to logger
----------------------- Captured stdout call ----------------------
text going to stdout
----------------------- Captured stderr call ----------------------
text going to stderr
==================== 2 failed in 0.02 seconds =====================
默認情況下,每個捕獲的日誌消息都顯示模組、行號、日誌級別和消息。
如果需要,可以通過傳遞特定的格式化選項,將日誌和日期格式指定為日誌記錄模組支持的任何格式
pytest --log-format="%(asctime)s %(levelname)s %(message)s" \
--log-date-format="%Y-%m-%d %H:%M:%S"
像這樣顯示失敗的測試
----------------------- Captured stdlog call ----------------------
2010-04-10 14:48:44 WARNING text going to logger
----------------------- Captured stdout call ----------------------
text going to stdout
----------------------- Captured stderr call ----------------------
text going to stderr
==================== 2 failed in 0.02 seconds =====================
這些選項也可以通過 pytest.ini
文件自定義
[pytest]
log_format = %(asctime)s %(levelname)s %(message)s
log_date_format = %Y-%m-%d %H:%M:%S
可以通過 --log-disable={logger_name}
禁用特定的 logger。此參數可以多次傳遞
pytest --log-disable=main --log-disable=testing
此外,可以使用以下命令完全禁用失敗測試中捕獲內容(stdout、stderr 和日誌)的報告
pytest --show-capture=no
caplog fixture¶
在測試中,可以更改捕獲的日誌消息的日誌級別。這由 caplog
fixture 支持
def test_foo(caplog):
caplog.set_level(logging.INFO)
默認情況下,級別設置在 root logger 上,但是為了方便起見,也可以設置任何 logger 的日誌級別
def test_foo(caplog):
caplog.set_level(logging.CRITICAL, logger="root.baz")
設置的日誌級別在測試結束時自動恢復。
也可以使用上下文管理器在 with
塊中臨時更改日誌級別
def test_bar(caplog):
with caplog.at_level(logging.INFO):
pass
同樣,默認情況下 root logger 的級別會受到影響,但是可以使用以下方法更改任何 logger 的級別
def test_bar(caplog):
with caplog.at_level(logging.CRITICAL, logger="root.baz"):
pass
最後,測試運行期間發送到 logger 的所有日誌都以 logging.LogRecord
實例和最終日誌文本的形式在 fixture 中提供。當您想要斷言消息的內容時,這很有用
def test_baz(caplog):
func_under_test()
for record in caplog.records:
assert record.levelname != "CRITICAL"
assert "wally" not in caplog.text
有關日誌記錄的所有可用屬性,請參閱 logging.LogRecord
類。
如果您只想確保某些消息已使用給定的嚴重程度和消息在給定的 logger 名稱下記錄,您也可以使用 record_tuples
def test_foo(caplog):
logging.getLogger().info("boo %s", "arg")
assert caplog.record_tuples == [("root", logging.INFO, "boo arg")]
您可以調用 caplog.clear()
來重置測試中捕獲的日誌記錄
def test_something_with_clearing_records(caplog):
some_method_that_creates_log_records()
caplog.clear()
your_test_method()
assert ["Foo"] == [rec.message for rec in caplog.records]
caplog.records
屬性僅包含當前階段的記錄,因此在 setup
階段中,它僅包含 setup 日誌,call
和 teardown
階段也是如此。
要訪問其他階段的日誌,請使用 caplog.get_records(when)
方法。 例如,如果您想確保使用特定 fixture 的測試永遠不會記錄任何警告,則可以在 teardown 期間檢查 setup
和 call
階段的記錄,如下所示
@pytest.fixture
def window(caplog):
window = create_window()
yield window
for when in ("setup", "call"):
messages = [
x.message for x in caplog.get_records(when) if x.levelno == logging.WARNING
]
if messages:
pytest.fail(f"warning messages encountered during testing: {messages}")
完整的 API 可在 pytest.LogCaptureFixture
找到。
警告
caplog
fixture 向 root logger 添加一個 handler 以捕獲日誌。如果在測試期間修改了 root logger,例如使用 logging.config.dictConfig
,則此 handler 可能會被刪除,並導致無法捕獲任何日誌。 為避免這種情況,請確保任何 root logger 配置僅添加到現有的 handlers。
實時日誌¶
通過將 log_cli
配置選項設置為 true
,pytest 將在日誌記錄發出時直接將其輸出到控制台。
您可以通過傳遞 --log-cli-level
來指定日誌級別,對於該級別,將級別等於或高於該級別的日誌記錄打印到控制台。 此設置接受日誌級別名稱或數值,如 logging’s documentation 中所示。
此外,您還可以指定 --log-cli-format
和 --log-cli-date-format
,如果未提供,它們將鏡像並默認設置為 --log-format
和 --log-date-format
,但僅適用於控制台日誌記錄 handler。
所有 CLI 日誌選項也可以在配置 INI 文件中設置。 選項名稱是
log_cli_level
log_cli_format
log_cli_date_format
如果您需要將整個測試套件日誌記錄調用記錄到文件中,則可以傳遞 --log-file=/path/to/log/file
。 此日誌文件默認以寫模式打開,這意味著它將在每次運行測試會話時被覆蓋。 如果您希望以追加模式打開文件,則可以傳遞 --log-file-mode=a
。 請注意,日誌文件位置的相對路徑,無論是在 CLI 上傳遞還是在配置文件中聲明,始終相對於當前工作目錄解析。
您還可以通過傳遞 --log-file-level
來指定日誌文件的日誌記錄級別。 此設置接受日誌級別名稱或數值,如 logging’s documentation 中所示。
此外,您還可以指定 --log-file-format
和 --log-file-date-format
,它們等於 --log-format
和 --log-date-format
,但適用於日誌文件日誌記錄 handler。
所有日誌文件選項也可以在配置 INI 文件中設置。 選項名稱是
log_file
log_file_mode
log_file_level
log_file_format
log_file_date_format
您可以調用 set_log_path()
以動態自定義 log_file 路徑。 此功能被認為是實驗性的。 請注意,set_log_path()
遵循 log_file_mode
選項。
自定義顏色¶
如果啟用了彩色終端輸出,則日誌級別會被著色。 通過 add_color_level()
支持從默認顏色更改或將顏色添加到自定義日誌級別。 例子
@pytest.hookimpl(trylast=True)
def pytest_configure(config):
logging_plugin = config.pluginmanager.get_plugin("logging-plugin")
# Change color on existing log level
logging_plugin.log_cli_handler.formatter.add_color_level(logging.INFO, "cyan")
# Add color to a custom log level (a custom log level `SPAM` is already set up)
logging_plugin.log_cli_handler.formatter.add_color_level(logging.SPAM, "blue")
警告
此功能及其 API 被認為是實驗性的,並且可能會在發布之間更改,恕不另行通知。
發布說明¶
此功能作為 pytest-catchlog 插件的直接替代品引入,它們彼此衝突。 當引入此功能時,已刪除與 pytest-capturelog
的向後兼容性 API,因此如果因此您仍然需要 pytest-catchlog
,則可以通過添加到 pytest.ini
來禁用內部功能
[pytest]
addopts=-p no:logging
pytest 3.4 中的不兼容更改¶
此功能在 3.3
中引入,並且在收到社區反饋後,在 3.4
中進行了一些不兼容的更改
除非通過
log_level
配置或--log-level
命令行選項顯式請求,否則不再更改日誌級別。 這允許用戶自行配置 logger 對象。 設置log_level
將設置全局捕獲的級別,因此如果特定測試需要低於此級別的級別,請使用caplog.set_level()
功能,否則該測試很容易失敗。實時日誌 現在默認禁用,可以通過將
log_cli
配置選項設置為true
來啟用。 啟用後,詳細程度會增加,因此每個測試的日誌記錄都是可見的。實時日誌 現在發送到
sys.stdout
,不再需要-s
命令行選項才能工作。
如果您想部分恢復版本 3.3
的日誌記錄行為,您可以將此選項添加到您的 ini
文件中
[pytest]
log_cli=true
log_level=NOTSET
有關導致這些更改的討論的更多詳細信息,請參閱 #3013。