如何在Python中测试特定的日志记录格式(使用"pytest"和"unittest&qu



我正在实现一种特定的日志记录格式,它将由另一个服务解析,用于日志记录/监控/警报目的。因此,日志记录格式需要非常具体。

我需要测试我的应用程序是否确实使用了我想要的格式。然而,无论出于何种原因,pytest都在使用自己的格式,而忽略了我的格式。

下面的可复制示例:

# logtest.py
##### LOGGING CONFIGURATiON
import logging
LOG_CONFIG_FORMAT = '%(asctime)s {%(process)d-%(thread)d} %(levelname)s 
%(name)s@%(lineno)d my_field_1=%(my_field_1)s my_field_2=%(my_field_2)s my_field_3=
%(my_field_3)s: %(message)s '
logging.basicConfig(level="DEBUG", format=LOG_CONFIG_FORMAT)

def get_logger(logger_name: str):
logger = logging.getLogger(logger_name)
adapter = logging.LoggerAdapter(logger, {
'my_field_2': None,
'my_field_1': None,
'my_field_3': None
})
return adapter

##### APPLICATION CODE
logger = get_logger(__name__)

def my_func():
for i in range(3):
if i > 1:
logger.extra = {
'my_field_2': 'BOOM!!!',
'my_field_1': 'BUST!!!',
'my_field_3': 'CRASH!!!'
}
logger.debug(i)

##### EXECUTE APPLICATION FUNCTION
my_func()

##### TESTING CODE
import unittest

class TestCase(unittest.TestCase):
def test_log(self):
with self.assertLogs(level="DEBUG") as cm:
my_func()
print(cm.output)
self.assertIn('my_field_1', cm.output[0])

如果我执行python logtest.py,我会得到正确的格式。如果我执行pytest logtest.py,我会得到pytest自己的格式。

不关心pytest的控制台输出,我如何测试应用程序日志的格式是否符合我的要求?

如果您只想测试格式化,则不需要使用basicConfig()assertLogs(),而是可以使用以下方法:

import logging
import unittest
import sys
class TestHandler(logging.Handler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.messages = []

def handle(self, record):
self.messages.append(self.format(record))
LOG_CONFIG_FORMAT = '%(asctime)s {%(process)d-%(thread)d} %(levelname)s 
%(name)s@%(lineno)d my_field_1=%(my_field_1)s my_field_2=%(my_field_2)s my_field_3=
%(my_field_3)s: %(message)s '
formatter = logging.Formatter(LOG_CONFIG_FORMAT)
handler = TestHandler()
handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
adapter = logging.LoggerAdapter(logger, {
'my_field_2': 'f2',
'my_field_1': 'f1',
'my_field_3': 'f3'
})
class TestCase(unittest.TestCase):
def test_formatting(self):
adapter.debug('Hello')
last = handler.messages[-1]
self.assertIn('my_field_1=f1 my_field_2=f2 my_field_3=f3: Hello ', last)

if __name__ == '__main__':
sys.exit(unittest.main())

您可以根据自己的具体需要调整上面的示例。您可以使用logging.handlers.MemoryHandler来代替TestHandler,然后询问缓冲记录中的特定条件。在这种情况下,由于您只是在测试格式化的输出,我使用了上面的方法来说明这一点。

最新更新