【问题标题】:How to use logging, pytest fixture and capsys?如何使用日志记录、pytest 夹具和 capsys?
【发布时间】:2016-07-26 15:38:21
【问题描述】:

我正在尝试对一些使用日志库的算法进行单元测试。

我有一个可以创建记录器的装置。

在我的第一个测试用例中,我不使用此夹具,而是使用打印记录到标准输出。此测试用例通过

在我的第二个测试用例中,我使用了这个夹具,但不是 pytest 文档中记录的那样。我只是在我的测试中调用相关函数来获取记录器。然后我使用记录器记录到标准输出。此测试用例通过

在我的第三个测试用例中,我使用了 pytest 文档中记录的这个夹具。夹具作为参数传递给测试函数。然后我使用记录器记录到标准输出。这个测试用例失败!它在标准输出中找不到任何内容。但是在错误消息中,它说我的日志在捕获的 stdout 调用中。

我做错了什么?

import pytest

import logging
import sys

@pytest.fixture()
def logger():

    logger = logging.getLogger('Some.Logger')
    logger.setLevel(logging.INFO)
    stdout = logging.StreamHandler(sys.stdout)
    logger.addHandler(stdout)

    return logger

def test_print(capsys):

    print 'Bouyaka!'

    stdout, stderr = capsys.readouterr()
    assert 'Bouyaka!' in stdout

    # passes

def test_logger_without_fixture(capsys):

    logger().info('Bouyaka!')

    stdout, stderr = capsys.readouterr()
    assert 'Bouyaka!' in stdout

    # passes

def test_logger_with_fixture(logger, capsys):

    logger.info('Bouyaka!')

    stdout, stderr = capsys.readouterr()
    assert 'Bouyaka!' in stdout

    # fails with this error:
    # >       assert 'Bouyaka!' in stdout
    # E       assert 'Bouyaka!' in ''
    #
    # tests/test_logging.py:21: AssertionError
    # ---- Captured stdout call ----
    # Bouyaka!

如果我顺便重新排序测试用例,没有任何变化。

【问题讨论】:

    标签: python unit-testing logging pytest


    【解决方案1】:

    非常感谢您的想法!

    反转logger, capsys,使logger 请求capsys 夹具并使用capfd 不进行任何更改。

    我尝试了pytest-catchlog 插件,它工作正常

    import pytest
    
    import logging
    
    @pytest.fixture()
    def logger():
    
        logger = logging.getLogger('Some.Logger')
        logger.setLevel(logging.INFO)
    
        return logger
    
    def test_logger_with_fixture(logger, caplog):
    
        logger.info('Bouyaka!')
    
        assert 'Bouyaka!' in caplog.text
    
        # passes!
    

    在我最初的测试中,我登录到 stdout 和 stderr 并捕获了它们。 这是一个更好的解决方案,因为我不需要这个调整来检查我的日志是否正常工作。

    好吧,现在我只需要重新编写所有测试以使用 caplog,但这是我自己的事 ;)

    现在我有了更好的解决方案,唯一剩下的就是了解我原来的测试用例 def test_logger_with_fixture(logger, capsys) 中的问题。

    【讨论】:

      【解决方案2】:

      我猜记录器是在设置 capsys 夹具之前(通过夹具)创建的。

      一些想法:

      • 使用pytest-catchlog插件
      • 可能反向logger, capsys
      • 使logger 请求capsys 夹具
      • 使用capfd,这是在不更改sys 的情况下进行更底层捕获

      【讨论】:

        【解决方案3】:

        从 pytest 3.3 开始,捕获日志消息的功能被添加到 pytest 核心。 caplog 夹具支持这一点:

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

        更多信息请访问documentation

        【讨论】:

          猜你喜欢
          • 2020-08-06
          • 2019-06-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-03
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          相关资源
          最近更新 更多