我正在尝试对使用日志库的一些算法进行单元测试。
我有一个创建记录器的夹具。
在我的第一个测试用例中,我不使用此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!
如果顺便重新排序测试用例,则没有任何变化。
答案 0 :(得分: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!
在我原来的测试中,我登录到stdout和stderr并捕获它们。 这是一个更好的解决方案,因为我不需要这个调整来检查我的日志是否正常工作。
好吧,现在我只需要修改我的所有测试以使用caplog,但这是我自己的事业;)
现在我唯一能找到更好的解决方案就是了解原始测试用例def test_logger_with_fixture(logger, capsys)
中的错误。
答案 1 :(得分:4)
我猜测在设置capsys
灯具之前(通过灯具)创建了记录器。
一些想法:
logger, capsys
logger
请求capsys
fixture capfd
sys
更低级别的捕捉
答案 2 :(得分:1)
从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