pytest
如果您正在使用以下方式编写测试pytest
,看一下名为caplog
这将为您捕获日志记录。它捕获所有发出的日志记录,然后您可以通过以下方式访问这些记录caplog.records
列表。每个元素都是一个实例logging.LogRecord
,这样您就可以轻松访问任何LogRecord属性 https://docs.python.org/3/library/logging.html#logrecord-attributes。例子:
# spam.py
import logging
logger=logging.getLogger(__name__)
def foo():
logger.info('bar')
# tests.py
import logging
from spam import foo
def test_foo(caplog):
foo()
assert len(caplog.records) == 1
record = next(iter(caplog.records))
assert record.message == 'bar'
assert record.levelno == logging.INFO
assert record.module == 'spam'
# etc
Install
该装置首次引入于pytest
插件名为pytest-capturelog
现在已被废弃。幸运的是,它有一个像样的叉子,名叫pytest-catchlog
, 已合并到pytest==3.3.0 https://docs.pytest.org/en/latest/changelog.html#pytest-3-3-0-2017-11-23最近。因此,如果您使用最新版本pytest
,您已经可以开始了;对于旧版本的pytest
, install pytest-catchlog来自 PyPI https://pypi.python.org/pypi/pytest-catchlog/.
Docs
眼下,pytest
不提供任何文档caplog
固定装置(或者至少我找不到),所以你可以参考pytest-catchlog
's 文档 https://pypi.python.org/pypi/pytest-catchlog/.
Plain unittest
If pytest
不是一个选项,我不会修补logging
完全 - 您可以简单地添加一个自定义处理程序来记录所有传入的日志。一个小例子:
# utils.py
import logging
class RecordsCollector(logging.Handler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.records = []
def emit(self, record):
self.records.append(record)
# tests.py
import logging
import unittest
from utils import RecordsCollector
from spam import foo
class SpamTests(unittest.TestCase):
def setUp(self):
self.collector = RecordsCollector()
logging.getLogger('spam').addHandler(self.collector)
def tearDown(self):
logging.getLogger('spam').removeHandler(self.collector)
def test_foo(self):
foo()
# same checks as in the example above
self.assertEqual(len(self.collector.records), 1)
record = next(iter(self.collector.records))
self.assertEqual(record.message, 'bar')
self.assertEqual(record.levelno, logging.INFO)
self.assertEqual(record.module, 'spam')
if __name__ == '__main__':
unittest.main()
然后,您可以扩展自定义处理程序并实现您需要的任何逻辑,例如收集记录dict
将日志级别映射到记录列表,或添加contextmanager
实现,这样您就可以开始和停止捕获测试中的记录:
from contextlib import contextmanager
@contextmanager
def record_logs():
collector = RecordsCollector()
logging.getLogger('spam').addHandler(collector)
yield collector
logging.getLogger('spam').removeHandler(collector)
def test_foo(self):
with utils.record_logs() as collector:
foo()
self.assertEqual(len(collector.records), 1)