如何使用日志记录,pytest fixture和capsys?

Mic*_*elM 8 python logging unit-testing pytest

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

我有一个创建记录器的夹具.

在我的第一个测试用例中,我不使用此fixture并使用print来登录stdout.这个测试用例通过.

在我的第二个测试用例中,我使用了这个fixture,但没有在pytest doc中记录.我只是在测试中调用相关函数来获取记录器.然后我使用记录器登录到stdout.这个测试用例通过.

在我的第3个测试用例中,我使用了pytest doc中记录的这个fixture.夹具作为参数传递给测试函数.然后我使用记录器登录到stdout.这个测试用例失败了!它在stdout中找不到任何东西.但是在错误消息中,它表示我的日志位于捕获的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!
Run Code Online (Sandbox Code Playgroud)

如果我按顺序重新排序测试用例,则没有任何变化.

Mic*_*elM 9

非常感谢你的想法!

反向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!
Run Code Online (Sandbox Code Playgroud)

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

好吧,现在我只需要修改我的所有测试以使用caplog,但这是我自己的业务;)

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


Ces*_*ssa 7

从 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
Run Code Online (Sandbox Code Playgroud)

更多信息可以在文档中找到


The*_*ler 4

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

一些想法:

  • 使用pytest-catchlog插件
  • 也许相反logger, capsys
  • 提出夹具logger请求capsys
  • 使用capfd更底层的捕获而不改变sys