如何管理日志记录¶
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}
禁用特定的日志记录器。此参数可以传递多次
pytest --log-disable=main --log-disable=testing
此外,还可以使用以下方法完全禁用对失败测试中捕获的内容(stdout、stderr 和日志)的报告
pytest --show-capture=no
caplog 固定装置¶
在测试中,可以更改捕获的日志消息的日志级别。这由 caplog
固定装置支持
def test_foo(caplog):
caplog.set_level(logging.INFO)
默认情况下,级别在根日志记录器上设置,但是为了方便,也可以设置任何日志记录器的日志级别
def test_foo(caplog):
caplog.set_level(logging.CRITICAL, logger="root.baz")
设置的日志级别将在测试结束时自动恢复。
还可以使用上下文管理器在 with
块中临时更改日志级别
def test_bar(caplog):
with caplog.at_level(logging.INFO):
pass
同样,默认情况下,根日志记录器的级别会受到影响,但可以使用以下方法更改任何日志记录器的级别
def test_bar(caplog):
with caplog.at_level(logging.CRITICAL, logger="root.baz"):
pass
最后,在测试运行期间发送到日志记录器的所有日志都以 logging.LogRecord
实例和最终日志文本的形式在固定装置上提供。当您想要断言消息的内容时,这非常有用
def test_baz(caplog):
func_under_test()
for record in caplog.records:
assert record.levelname != "CRITICAL"
assert "wally" not in caplog.text
有关日志记录的所有可用属性,请参阅 logging.LogRecord
类。
如果您只想确保在给定的日志记录器名称下使用给定的严重性和消息记录了某些消息,还可以使用 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
阶段中,它仅包含设置日志,与 call
和 teardown
阶段相同。
要访问其他阶段的日志,请使用 caplog.get_records(when)
方法。例如,如果您要确保使用特定固定装置的测试永远不会记录任何警告,则可以在拆除期间像这样检查 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
固定装置会向根日志记录器添加一个处理程序来捕获日志。如果在测试期间修改了根日志记录器,例如使用 logging.config.dictConfig
,则可能会移除此处理程序,并导致不捕获任何日志。为避免这种情况,请确保任何根日志记录器配置仅添加到现有处理程序。
实时日志¶
通过将 log_cli
配置选项设置为 true
,pytest 将在记录直接输出到控制台时输出日志记录。
你可以通过传递 --log-cli-level
来指定日志记录的日志级别,该级别或更高级别的日志记录将打印到控制台。此设置接受 日志记录文档 中看到的日志记录级别名称或数字值。
此外,你还可以指定 --log-cli-format
和 --log-cli-date-format
,如果未提供,它们将镜像并默认为 --log-format
和 --log-date-format
,但仅应用于控制台日志记录处理程序。
所有 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
来指定日志文件的日志级别。此设置接受 日志记录文档 中看到的日志记录级别名称或数字值。
此外,你还可以指定 --log-file-format
和 --log-file-date-format
,它们等于 --log-format
和 --log-date-format
,但应用于日志文件日志记录处理程序。
所有日志文件选项也可以在配置文件 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
命令行选项明确请求,否则不再更改日志级别。这允许用户自行配置记录器对象。设置log_level
将设置全局捕获的级别,因此,如果特定测试需要比此级别更低的级别,请使用caplog.set_level()
功能,否则该测试容易失败。实时日志 现在默认禁用,可以通过将
log_cli
配置选项设置为true
来启用。启用后,详细级别增加,以便每个测试的日志可见。实时日志 现在发送到
sys.stdout
,不再需要-s
命令行选项才能工作。
如果你想部分恢复 3.3
版本的日志记录行为,可以将此选项添加到 ini
文件
[pytest]
log_cli=true
log_level=NOTSET
有关导致这些更改的讨论的更多详细信息,可以在 问题 #3013 中阅读。