在Pycharm下运行Django测试的日志输出

12
当使用PyCharm下的django.test.TestCase来运行/调试单个测试时,logging.logger消息不会显示。 我已尝试按如何在PyCharm中进行单元测试时查看日志消息?建议设置logging.basicConfig(level=logging.DEBUG),但也没有帮助。 我怀疑可能是django的TestCase设置干扰了。
在测试设置或运行器配置中是否有其他方法可以打开测试运行的调试记录?
我目前在我的settings.py中设置的记录为:
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        },
        'file': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': '/var/log/em/mcqueen-dev.log',
            'when': 'midnight',
            'formatter': 'verbose',
        },
    },
    'formatters': {
        'verbose': {
            'format': '%(asctime)s.%(msecs).03d - %(process)d - %(thread)d - %(levelname)8s - %(filename)s:%(lineno)d - %(funcName)s - %(message)s'
        },
        'simple': {
            'format': '%(asctime)s - %(levelname)s %(message)s'
        },
    },
    'loggers': {
        'mcqueen_api': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG')
        },
        'mcqueen_app': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG')
        },
        'mcqueen_base': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG')
        },
    },
}

请展示你的 settings.py 文件? - Son Lam
1
你能分享一下我建议的django_test配置在你的情况下是怎样的吗? - Son Lam
4个回答

11

当我在PyCharm上为Django项目编写测试时,想要查看日志,我会将以下代码片段放入测试文件中:

import logging
logger = logging.getLogger(__name__)
logging.disable(logging.NOTSET)
logger.setLevel(logging.DEBUG)

在运行Django测试时,禁用日志的级别设置得很高(为50),将其降低(例如上面代码中的第3行)会导致日志被显示出来(或保存到文件中-根据使用的日志处理程序而定)。


2
在stackoverflow上,这个主题解释了你的日志输出未显示到控制台的可能原因。显然,Django的单元测试运行器替换了全局sys.stdout/sys.stderr,但从Django设置指定的StreamHandler仍与原始的sys.stdout/sys.stderr绑定在一起。修复方法是在测试模块中向记录器添加一个流处理程序,根据执行期间sys.stdout/sys.stderr的值。
如果您希望记录器记录所有测试用例方法的控制台,则最好使用自定义基类(有关更多详细信息,请参见链接的主题)来包装添加/删除setUp/tearDown的逻辑。
我更喜欢使用装饰器包装单个测试方法。例如(使用Sơn Lâm的答案提供的“django_test”记录器配置):
import logging
import sys
from contextlib import contextmanager

from django.test import TestCase

@contextmanager
def streamhandler_to_console(lggr):
    # Use 'up to date' value of sys.stdout for StreamHandler,
    # as set by test runner.
    stream_handler = logging.StreamHandler(sys.stdout)
    lggr.addHandler(stream_handler)
    yield
    lggr.removeHandler(stream_handler)

def testcase_log_console(lggr):
    def testcase_decorator(func):
        def testcase_log_console(*args, **kwargs):
            with streamhandler_to_console(lggr):
                return func(*args, **kwargs)
        return testcase_log_console
    return testcase_decorator

logger = logging.getLogger('django_test')

class SomeTestCase(TestCase):
    @testcase_log_console(logger)
    def test_something(self):    
        logger.info('show something to console.')

2
我认为它会起作用。
在settings.py文件中配置日志。
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'verbose': {
    'format': "[%(asctime)s] %(levelname)s %(message)s",
                'datefmt': "%d/%b/%Y %H:%M:%S"
            }
        },
        'handlers': {
            'file': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',
                'filename': '/var/log/django_practices.log',
                'formatter': 'verbose'
            },
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
                'stream': sys.stdout,
                'formatter': 'verbose'
            },
        },
        'loggers': {

            'django_test': {
                'handlers': ['file', 'console'],
                'level': 'DEBUG',
            },
            'name_your_app': {
                'handlers': ['file', 'console'],
                'level': 'DEBUG',
            }

        }
    }

在单元测试文件中

import logging
logger = logging.getLogger('django_test')
logger.info('test_log')

日志将会出现。


没有运气。在PyCharm测试输出中仍然没有日志记录输出。 - Arne Claassen
你能在设置文件中为 'django_test' 添加日志配置吗? - Son Lam
是的。输出总是只显示有关创建测试数据库和销毁它的 Django 消息,没有日志记录。但是,如果我在我的测试中放置 print(),它确实会显示在那里,因此它肯定是控制台窗口。 - Arne Claassen
除了上述设置之外,我还添加了你建议的“django-test”块。 - Arne Claassen

0

我认为这与您正在使用的测试运行程序有关 - 假设您正在使用PyCharm中内置的Django测试设置,那么它应该已经设置了一个环境变量PYTHONUNBUFFERED=1,我认为这就是使输出直接打印而不被缓冲并仅在最后显示(这是我所假设的)的原因。检查测试配置中是否设置了此选项,如果没有,请尝试设置。

另请参见: Pycharm单元测试交互式调试命令行无法工作(特别是如果您使用不同的测试运行程序)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接