我想测试一个在初始化时执行日志记录的类,并将日志保存到本地文件。因此,我在模拟日志逻辑片段以避免测试时的文件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()
。考虑到:
我认为猴子修补应该在课堂上进行抽象。我们如何在课堂级别抽象monkeypatching?我希望解决方案类似于以下内容:
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>)
答案 0 :(得分:1)
更清洁的实施:
# conftest.py
import pytest
@pytest.fixture(autouse=True)
def dont_configure_logging(monkeypatch):
monkeypatch.setattr('twsapp.client.initialise_logger', lambda x: None)
您不需要使用灯具标记单个测试,也不需要注入它,无论如何都会应用。
如果需要对记录的记录进行断言,请注入caplog夹具。请注意,您不需要配置记录器以进行记录断言 - caplog
fixture将注入所需的处理程序以便正常工作。如果要自定义用于测试的日志记录格式,请在pytest.ini
或[tool:pytest]
setup.cfg
部分下执行此操作。
答案 1 :(得分:0)
在练习中,我把夹具放在/test/conftest.py
中。实际上,pytest会自动从名为conftest.py
的文件中加载fixture,并且可以在测试会话期间应用于任何模块。
from _pytest.monkeypatch import MonkeyPatch
@pytest.fixture(scope="class")
def suppress_logger(request):
"""Source: https://github.com/pytest-dev/pytest/issues/363"""
# BEFORE running the test.
monkeypatch = MonkeyPatch()
# Provide dotted path to method or function to be mocked.
monkeypatch.setattr('twsapp.client.initialise_logger', lambda x: None)
# DURING the test.
yield monkeypatch
# AFTER running the test.
monkeypatch.undo()
import pytest
@pytest.mark.usefixtures("suppress_logger")
class TestClass:
def test_1(self):
assert True
def test_2(self):
assert True
def test_3(self):
assert True
编辑:我最终在conftest.py
中使用了以下内容@pytest.fixture(autouse=True)
def suppress_logger(mocker, request):
if 'no_suppress_logging' not in request.keywords:
# If not decorated with: @pytest.mark.no_suppress_logging_error
mocker.patch('logging.error')
mocker.patch('logging.warning')
mocker.patch('logging.debug')
mocker.patch('logging.info')