【发布时间】:2018-07-16 10:06:18
【问题描述】:
我想测试一个在初始化时记录日志并将日志保存到本地文件的类。因此,我正在模拟日志记录逻辑,以避免在测试时进行文件 IO。这是代表我如何构建测试的伪代码
class TestClass:
def test_1(self, monkeypatch):
monkeypatch.setattr('dotted.path.to.logger', lambda *args: '')
assert True
def test_2(self, monkeypatch):
monkeypatch.setattr('dotted.path.to.logger', lambda *args: '')
assert True
def test_3(self, monkeypatch):
monkeypatch.setattr('dotted.path.to.logger', lambda *args: '')
assert True
注意monkeypatch.setattr() 是如何在所有方法中复制粘贴的。考虑到:
- 我们事先知道所有调用方法都需要以相同的方式进行猴子修补,并且
- 可能会忘记猴子补丁新方法,
我认为猴子补丁应该在类级别进行抽象。我们如何在类级别抽象猴子补丁?我希望解决方案类似于以下内容:
import pytest
class TestClass:
pytest.monkeypatch.setattr('dotted.path.to.logger', lambda *args: '')
def test_1(self):
assert True
def test_2(self):
assert True
def test_3(self):
assert True
这是配置记录器的地方。
def initialise_logger(session_dir: str):
"""If missing, initialise folder "log" to store .log files. Verbosity:
CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET."""
os.makedirs(session_dir, exist_ok=True)
logging.basicConfig(filename=os.path.join(session_dir, 'session.log'),
filemode='a',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S',
format='|'.join(['(%(threadName)s)',
'%(asctime)s.%(msecs)03d',
'%(levelname)s',
'%(filename)s:%(lineno)d',
'%(message)s']))
# Adopt NYSE time zone (aka EST aka UTC -0500 aka US/Eastern). Source:
# https://stackoverflow.com/questions/32402502/how-to-change-the-time-zone-in-python-logging
logging.Formatter.converter = lambda *args: get_now().timetuple()
# Set verbosity in console. Verbosity above logging level is ignored.
console = logging.StreamHandler()
console.setLevel(logging.ERROR)
console.setFormatter(logging.Formatter('|'.join(['(%(threadName)s)',
'%(asctime)s',
'%(levelname)s',
'%(filename)s:%(lineno)d',
'%(message)s'])))
logger = logging.getLogger()
logger.addHandler(console)
class TwsApp:
def __init__(self):
initialise_logger(<directory>)
【问题讨论】:
-
请编辑您的帖子以添加配置记录器的代码部分。完成后联系我,我会添加答案。
-
@wim 用代码更新了问题。我最终使用了一个带有 scope='class' 的 python.fixture 并使用 MonkeyPatch() form _pytest.monkeypatch import MonkeyPatch。我已经发布了我的解决方案,但如果它更优雅,我很乐意接受!
-
你在正确的轨道上,但你并没有真正正确地使用 monkeypatch 夹具(它不应该像那样手动实例化)。我已经添加了答案。
标签: python logging mocking pytest monkeypatching