阅读(498) (1)

pytest 测试输出和结果-管理日志记录

2022-03-21 11:31:05 更新

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

此外,可以通过以下方式完全禁用对失败测试的捕获内容(​stdout​、​stderr ​和​logs​)的报告:

pytest --show-capture=no

caplog fixture

在测试内部,可以更改捕获的日志消息的日志级别。这是由​caplog fixture​支持的:

def test_foo(caplog):
    caplog.set_level(logging.INFO)
    pass

默认情况下,级别是在根记录器上设置的,但是为了方便起见,也可以设置任何记录器的日志级别:

def test_foo(caplog):
    caplog.set_level(logging.CRITICAL, logger="root.baz")
    pass

设置的日志级别会在测试结束时自动恢复。

也可以使用上下文管理器临时更改 ​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

最后,在测试运行期间发送给记录器的所有日志都可以在​fixture​上以日志记录的形式获得。当你想要对消息的内容进行断言时,这很有用:

def test_baz(caplog):
    func_under_test()
    for record in caplog.records:
        assert record.levelname != "CRITICAL"
    assert "wally" not in caplog.text

如果您只想确保某些消息已记录在具有给定严重性和消息的给定记录器名称下,您还可以使用 ​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​ 属性仅包含来自当前阶段的记录,因此在设置阶段内它仅包含设置日志,与调用和拆卸阶段相同。

要从其他阶段访问日志,请使用​caplog.get_records(when)​方法。例如,如果你想确保使用某个​fixture​的测试不会记录任何警告,你可以像这样检查安装和调用阶段的记录:

@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(
                "warning messages encountered during testing: {}".format(messages)
            )

实时日志

通过将 ​log_cli配置选项设置为 ​true,pytest 将输出日志记录,因为它们直接发送到控制台。

您可以通过传递 ​--log-cli-level​ 指定将具有相同或更高级别的日志记录打印到控制台的日志记录级别。 此设置接受 python 文档中看到的日志记录级别名称或整数作为日志记录级别 ​num​。

此外,您还可以指定 ​--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-level​ 来指定日志文件的日志记录级别。 此设置接受 python 文档中所见的日志级别名称(即大写的级别名称)或整数作为日志级别 ​num​。

此外,您还可以指定 ​--log-file-format​ 和 ​--log-file-date-format​ 等于 ​--log-format​ 和 ​--log-date-format​ 但应用于日志文件日志记录处理程序。

所有日志文件选项也可以在配置 ​INI文件中设置。 选项名称是:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

您可以调用 ​set_log_path()​ 来动态自定义 ​log_file ​路径。

自定义颜色

如果启用了彩色终端输出,则日志级别是彩色的。 通过 ​add_color_level()​ 支持从默认颜色更改或在自定义日志级别上添加颜色。 例如:

@pytest.hookimpl
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")

此功能是作为 ​pytest-catchlog​ 插件的替代品引入的,它们相互冲突。 引入此功能时,带有 ​pytest-capturelog​ 的向后兼容性 API 已被删除,因此如果您仍然需要 ​pytest-catchlog​,您可以通过添加到 ​pytest.ini​ 来禁用内部功能:

[pytest]
    addopts=-p no:logging