我正在使用一个简单的基于单元测试的测试运行器来测试我的Django应用程序。
我的应用程序本身被配置为在settings.py中使用一个基本的日志记录器:
logging.basicConfig(level=logging.DEBUG)
并在我的应用程序代码使用:
logger = logging.getLogger(__name__)
logger.setLevel(getattr(settings, 'LOG_LEVEL', logging.DEBUG))
但是,在运行单元测试时,我想禁用日志记录,这样它就不会使测试结果输出混乱。有没有一种简单的方法以全局方式关闭日志记录,这样当我运行测试时,特定于应用程序的日志记录器就不会把东西写到控制台了?
在我希望暂时抑制特定记录器的情况下,我写了一个我发现有用的小上下文管理器:
from contextlib import contextmanager
import logging
@contextmanager
def disable_logger(name):
"""Temporarily disable a specific logger."""
logger = logging.getLogger(name)
old_value = logger.disabled
logger.disabled = True
try:
yield
finally:
logger.disabled = old_value
然后你可以这样使用它:
class MyTestCase(TestCase):
def test_something(self):
with disable_logger('<logger name>'):
# code that causes the logger to fire
这样做的好处是,一旦with操作完成,记录器将被重新启用(或设置回其先前的状态)。
我的一些测试包含关于日志输出的断言,因此更改日志级别会破坏它们。相反,我改变了Django LOGGING设置,在运行测试时使用NullHandler:
if 'test' in sys.argv:
_LOG_HANDLERS = ['null']
else:
_LOG_HANDLERS = ['console']
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple',
},
},
'loggers': {
'django': {
'handlers': _LOG_HANDLERS,
'propagate': True,
'level': 'INFO',
},
}
}
有时你想要日志,有时不想要。我在settings。py中有这段代码
import sys
if '--no-logs' in sys.argv:
print('> Disabling logging levels of CRITICAL and below.')
sys.argv.remove('--no-logs')
logging.disable(logging.CRITICAL)
所以如果你使用——no-logs选项运行测试,你将只得到关键日志:
$ python ./manage.py tests --no-logs
> Disabling logging levels of CRITICAL and below.
如果您想加快持续集成流的测试,这是非常有用的。
如果你想在2021年或以后考虑这个问题,你可能问错了问题
在现代版本的Django*中,使用开箱即用的配置,测试应该不会在屏幕上产生任何日志记录。因此,如果你在问这个问题,真正的答案可能是“某些东西配置错误”。这是因为(默认情况下):
打印日志消息到控制台需要debug为True
测试运行DEBUG=False
因此,如果您使用的记录器与在LOGGING['loggers']中定义的记录器相匹配,并且由“控制台”处理程序处理,那么测试应该不会在屏幕上产生任何日志记录。
如果你在测试中看到了什么,你也
日志记录器的名称与在设置中定义的内容不匹配。日志记录
正在使用DEBUG=True运行测试(需要重写)
已经从控制台处理程序的过滤器中删除了“require_debug_true”。
*现代版本的意思是:2.1及以上,即不古老。