如何在pytest中抑制第三方日志

问题描述 投票:0回答:4

我们刚刚从

nose
切换到
pytest
,并且似乎没有抑制第三方日志记录的选项。在
nose
配置中,我们有以下行:

logging-filter=-matplotlib,-chardet.charsetprober,-PIL,-fiona.env,-fiona._env

其中一些日志非常啰嗦,尤其是

matplotlib
,我们不想看到输出,只想从我们的日志中输出。

但我在

pytest
中找不到等效的设置。是否可以?我错过了什么吗?谢谢。

python logging pytest nose
4个回答
10
投票

我的方法是创建一个记录器名称列表,必须在conftest.py中禁用其日志。

例如,如果我想禁用一个名为

app
的记录器,那么我可以编写一个 conftest.py ,如下所示:

import logging

disable_loggers = ['app']

def pytest_configure():
    for logger_name in disable_loggers:
        logger = logging.getLogger(logger_name)
        logger.disabled = True

然后运行我的测试:

import logging

def test_brake():
    logger = logging.getLogger("app")
    logger.error("Hello there")
    assert True

正在收集...已收集 1 件

test_car.py::test_brake 通过
[100%]

================================ 0.01s 内有 1 个通过 ============== =================

然后,你好不存在,因为名称为

app
的记录器在conftest.py中被禁用。

但是,如果我将测试中的记录器名称更改为

app2
并再次运行测试:

import logging

def test_brake():
    logger = logging.getLogger("app2")
    logger.error("Hello there")
    assert True

正在收集...已收集 1 件

test_car.py::test_brake -------------------------------- 实时日志通话 --------------- ------------------ 错误 app2:test_car.py:5 你好 通过了
[100%]

================================ 0.01s 内有 1 个通过 ============== =================

正如您所看到的,Hello there 存在,因为具有

app2
的记录器未禁用。

结论

基本上,您可以执行相同的操作,但只需将不需要的记录器名称添加到conftest.py,如下所示:

import logging

disable_loggers = ['matplotlib', 'chardet.charsetprober', <add more yourself>]

def pytest_configure():
    for logger_name in disable_loggers:
        logger = logging.getLogger(logger_name)
        logger.disabled = True

3
投票

除了我确信您已在文档中阅读过的调整日志记录级别或根本不显示任何日志输出的能力之外,我想到的唯一方法是一般配置您的日志记录。 假设所有这些包都使用标准库日志记录工具,您可以使用多种选项来配置记录的内容。请查看

高级教程

,以更好地了解您的选项。 如果您不想在一般情况下为应用程序配置日志记录,而只想在测试期间配置日志记录,则可以使用

pytest_configure

pytest_sessionstart 挂钩来执行此操作,您可以将其放置在测试文件根目录的 conftest.py 中等级制度。

然后我看到三个选项:

    暴力方式是使用
  1. fileConfig

    dictConfig
    的默认行为来禁用所有现有的记录器。在你的
    conftest.py
    :
    import logging.config
    
    
    def pytest_sessionstart():
        # This is the default so an empty dictionary should work, too.
        logging.config.dictConfig({'disable_existing_loggers': True})
    

  2. 更微妙的方法是更改单个记录器的级别或禁用它们。举个例子:
  3. import logging.config def pytest_sessionstart(): logging.config.dictConfig({ 'disable_existing_loggers': False, 'loggers': { # Add any noisy loggers here with a higher loglevel. 'matplotlib': {'level': 'ERROR'} } })

  4. 最后,您可以使用
  5. pytest_addoption

    挂钩添加与您提到的类似的命令行选项。同样,在测试层次结构的根部将以下内容放入 conftest.py:

    def pytest_addoption(parser):
        parser.addoption(
            "--logging-filter",
            help="Provide a comma-separated list of logger names that will be "
            "disabled."
        )
    
    
    def pytest_sessionstart(pytestconfig):
        for logger_name in pytestconfig.getoption("--logging-filter").split(","):
            # Use `logger_name.trim()[1:]` if you want the `-name` CLI syntax.
            logger = logging.getLogger(logger_name.trim())
            logger.disabled = True
    

    然后您可以通过以下方式调用 pytest:

    pytest --logging-filter matplotlib,chardet,...

    
    
  6. pytest 的默认方法是隐藏所有日志,但提供
caplog

固定装置来检查测试用例中的日志输出。如果您正在寻找特定的日志行,这将非常强大。所以问题是为什么您需要在测试套件中查看这些日志?

    


1
投票
conftest.py

添加日志过滤器看起来可能很有用,我会在将来的某个时候再讨论这一点。但现在,我们只是静默应用程序中的日志。当应用程序运行时,我们在任何时候都看不到它们,而不仅仅是在测试期间。

# Hide verbose third-party logs
for log_name in ('matplotlib', 'fiona.env', 'fiona._env', 'PIL', 'chardet.charsetprober'):
    other_log = logging.getLogger(log_name)
    other_log.setLevel(logging.WARNING)



0
投票

来自他们的

文档

可以通过 --log-disable={logger_name} 禁用特定记录器。这 参数可以多次传递:

pytest --log-disable=main --log-disable=testing


如果您使用的是 pytest>=7.3,您可以使用:

pytest --log-disable=matplotlib --log-disable=chardet.charsetprober --log-disable=PIL --log-disable=fiona.env --log-disable=Fiona._env

    

© www.soinside.com 2019 - 2024. All rights reserved.