在 Pycharm 下记录运行 django 测试的输出

Posted

技术标签:

【中文标题】在 Pycharm 下记录运行 django 测试的输出【英文标题】:Logging output running django tests under Pycharm 【发布时间】:2016-07-27 04:37:06 【问题描述】:

在 PyCharm 下使用 django.test.TestCase 运行/调试单个测试时,不会显示 logging.logger 消息。我尝试按照How can I see log messages when unit testing in 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 文件? 你能分享一下我建议的 django_test 配置吗? 【参考方案1】:

当我想在 PyCharm 中对 Django 项目进行测试时查看日志时,我会将这段 sn-p 代码放入带有 test 的文件中:

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

虽然禁用日志的运行 Django 测试级别设置为高(至 50),但降低它(如上面代码中的第 3 行)将导致日志将显示(或保存到文件 - 取决于日志处理程序)正在使用)。

【讨论】:

【参考方案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 测试输出中仍然没有日志输出 你是否在设置文件中添加了'django_test'的日志配置? 是的。输出总是只显示 django 关于创建测试数据库然后销毁它的消息,没有日志记录。但是,如果我将 print() 放在我的测试中,它确实会显示在那里,所以它绝对是一个控制台窗口 除了上述设置外,我还添加了您建议的“django-test”块【参考方案3】:

This thread on *** 解释了您的日志输出未显示到控制台的可能原因。显然,django 的 unittest runner 替换了全局的 sys.stdout/sys.stderr,但是从 django 设置中指定的 StreamHandler 仍然与原始的 sys.stdout/sys.stderr 绑定。解决方法是根据执行期间 sys.stdout/sys.stderr 的值,在测试模块中将流处理程序添加到您的记录器。

如果您希望记录器为您的测试用例的所有方法记录到控制台,那么您可能最好使用自定义基类(有关更多详细信息,请参阅链接到线程)来包装在 setUp 中添加/删除的逻辑/拆卸。

我更喜欢使用装饰器而不是单独的包装测试方法。例如(使用 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.')

【讨论】:

【参考方案4】:

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

另请参阅:Pycharm unit test interactive debug command line doesn't work(尤其是在您使用不同的测试运行程序时)

【讨论】:

以上是关于在 Pycharm 下记录运行 django 测试的输出的主要内容,如果未能解决你的问题,请参考以下文章

pycharm配置运行django项目步骤

Django 仅使用 pycharm 测试错误 - 不是终端 |应用尚未加载

pycharm上运行django服务器端ip地址访问

从 PyCharm 社区版中的鼠标右键单击上下文菜单运行/调试 Django 应用程序单元测试?

PyCharm下创建并运行我们的第一个Django项目

windows7下 pycharm运行django 崩溃 提示 python已经停止工作