如何使用日志记录,Pytest Fixture和Capsys? [英] How to use logging, pytest fixture and capsys?

查看:197
本文介绍了如何使用日志记录,Pytest Fixture和Capsys?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to unit-test some algorithm that uses logging library.

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

I have a fixture that creates a logger.

在我的第一个测试用例中,我不使用此固定装置,而是使用打印记录到标准输出.此测试用例通过.

In my 1st test case, I do not use this fixture and uses a print to log to stdout. This test case passes.

在我的第二个测试用例中,我使用了这个固定装置,但不如pytest文档中记录的那样.我只是在测试中调用关联的函数来获取记录器.然后,我使用记录器登录到stdout.此测试用例通过.

In my 2nd test case, I use this fixture, but not as documented in pytest doc. I just call the associated function in my test to get the logger. Then I use the logger to log to stdout. This test case passes.

在我的第3个测试用例中,我使用了pytest文档中记录的固定装置.固定装置作为参数传递给测试函数.然后,我使用记录器登录到stdout.此测试用例失败!它在stdout中找不到任何内容.但是在错误消息中,它说我的日志在捕获的stdout调用中.

In my 3rd test case, I use this fixture as documented in pytest doc. The fixture is passed as an argument to the test function. Then I use the logger to log to stdout. This test case fails! It does not find anything in stdout. But in the error message, it says that my log is in the captured stdout call.

我在做什么错了?

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!

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

There is no change if I reorder the test cases by the way.

推荐答案

非常感谢您的想法!

反转logger, capsys,使logger请求capsys固定装置,并使用capfd不做任何更改.

Reverse logger, capsys, make logger request the capsys fixture and use capfd do not change anything.

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

I tried pytest-catchlog plugin and it works fine!

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并捕获了它们. 这是一个更好的解决方案,因为我不需要进行此调整即可检查我的日志是否工作正常.

In my original tests, I logged to stdout and stderr and captured them. This is an even better solution, as I do not need this tweak to check that my logs work fine.

好吧,现在我只需要重做所有测试即可使用caplog,但这是我自己的事;)

Well, now I just need to rework all my tests to use caplog, but this is my own business ;)

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

The only thing left, now that I have a better solution, is to understand what is wrong in my original test case def test_logger_with_fixture(logger, capsys).

这篇关于如何使用日志记录,Pytest Fixture和Capsys?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆