django - 如何使用用于日志记录的 Django 设置配置正确地使用 unittest 进行 assertLogs 测试?

标签 django python-3.x logging django-unittest

我有一个用于登录我的 django 项目的设置,我想使用 assertLogs 进行测试。

我使用了文档中提供的示例:https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertLogs

with self.assertLogs('foo', level='INFO') as cm:
   logging.getLogger('foo').info('first message')
   logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
                             'ERROR:foo.bar:second message'])

我的 Django 设置如下:
LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
        'standard': {
            'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
        },
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR + '/logs/default.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'debug_file': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR + '/logs/debug.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'warning_file': {
            'level':'WARNING',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR + '/logs/warning.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'info_file': {
            'level':'INFO',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR + '/logs/info.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'error_file': {
            'level':'ERROR',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR + '/logs/error.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
        },
        'emails': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR + '/logs/emails.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
        },
        'debug_logger': {
            'handlers': ['debug_file'],
            'level': 'DEBUG',
            'propagate': True
        },
        'info_logger': {
            'handlers': ['info_file'],
            'level': 'INFO',
            'propagate': True
        },
        'error_logger': {
            'handlers': ['error_file'],
            'level': 'ERROR',
            'propagate': True
        },
        'django.request': {
            'handlers': ['default', 'mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
        'emails': {
            'handlers': ['emails'],
            'level': 'DEBUG',
            'propagate': True
        },

    }
}

我的测试:
from django.test import TestCase
import unittest
import logging

class LoggerTestCase(unittest.TestCase):
    def test_message_logger(self):
        with self.assertLogs('loggers', level='INFO') as logs:
            logging.getLogger('debug_logger').debug('debug message')
            logging.getLogger('info_logger').info('info message')
            logging.getLogger('warning_logger').warning('warning message')
            logging.getLogger('error_logger').error('error message')
            logging.getLogger('critical_logger').critical('critical message')
        self.assertEqual(logs.output, ['INFO:loggers.debug:debug message', 
            'ERROR:loggers.info:info message', 
            'WARNING:loggers.warning:warning message', 
            'ERROR:loggers.error:error message', 
            'CRITICAL:loggers.critical:critical message'
            ])

但我收到此错误:
Traceback (most recent call last):
line 16, in test_message_logger
    logging.getLogger('critical_logger').critical('critical message')
AssertionError: no logs of level INFO or higher triggered on loggers

我希望正确使用 assertLogs。我已经在我的 View 中使用了我的打印消息并且它工作正常,那么我该如何解决这个错误?我无法发现我的错误在哪里

任何帮助将不胜感激

更新

更换 loggers来自 critical_logger我收到此错误:
Traceback (most recent call last):
  File 
 line 19, in test_message_logger
    'CRITICAL:loggers.critical:critical message'
AssertionError: Lists differ: ['CRITICAL:critical_logger:critical message'] != ['INFO:loggers.debug:debug message', 'ERROR[149 chars]age']

最佳答案

assertLogs 的第一个参数是您希望日志记录发生的记录器。您没有使用 loggers 的任何记录器命名空间 - 这就是它不起作用的原因。

logging.getLogger('critical_logger').critical('critical message')

在这里,您使用的记录器是 critical_logger .为了工作,你的断言必须是:
self.assertLogs('critical_logger', level='INFO')

我认为困惑在于您首先登录的方式 - 在测试中为每一行使用不同的记录器是没有意义的( debug_loggerinfo_logger 等)。您需要使用一个记录器,并且您的测试断言需要在该记录器中查找日志。

关于django - 如何使用用于日志记录的 Django 设置配置正确地使用 unittest 进行 assertLogs 测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56104967/

相关文章:

python-3.x - 无法从 Python 代码连接到 Cassandra

python - 情节显示 Jupyter 中的错误点

python - 测试 Python 装饰器?

python - Django:如何从多个模型中按日期获取对象?

空 IntegerField 上的 Django 表单验证

python - pandas.crosstab 切片并添加总计

django - MongoEngine 中对 EmbeddedDocumentListField 的大于 (gte) 查询

ruby - Bundler 删除记录器的格式?

logging - 更改 GCP 中 Stackdriver Logging 日志的 header

java获取类包的名称