【问题标题】:Nose test fails when Unittest does not当 Unittest 没有时鼻子测试失败
【发布时间】:2015-03-05 19:06:40
【问题描述】:

我们发现 Python 鼻子测试的结果与单元测试的结果之间存在奇怪的差异。这是导致问题的代码,尤其是最后一行:

import logging

class ClassThatLogsBadly:
    log = logging.getLogger(__name__)

    def method_that_logs_badly(self):
        self.log.error('A message', 'Another string')
        return ('I ran')

上面的log 是从 Python 的日志库中检索到的,并且在调用时会产生问题,因为以下原因(来自 Python 库:logging/__init__.py:328):

def getMessage(self):
    """
    Return the message for this LogRecord.

    Return the message for this LogRecord after merging any user-supplied
    arguments with the message.
    """
    msg = str(self.msg)
    if self.args:
        msg = msg % self.args
    return msg

如您所见,它尝试将Another string 拼接到A message,但后者没有要填充的有效插槽(%s 类型),因此无法执行此操作。这是一个known problem,解决方案是在记录器之外格式化你的东西。但是,我们的问题是进行测试以确保完成此操作。

对使用 unittest 或 py.test 调用日志库的代码运行测试不会引发失败。用鼻子运行相同的测试会导致错误,并且测试会失败。我们的大部分构建内容都是围绕 py.test 库构建的,并且没有这个测试失败是令人担忧的:我们不确定这是否是出于某种原因的预期行为,这些库之间处理的根本区别是什么,以及通常是什么去做吧。

我们使用的是 Python 3.4。这是运行此代码的示例测试:

import logging
import unittest

from mycode import ClassThatLogsBadly

class TestClassThatLogsBadly(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_method_that_logs_badly(self):
        clz = ClassThatLogsBadly()
        result = clz.method_that_logs_badly()
        self.assertEquals('I ran', result)

【问题讨论】:

    标签: python nose unit-testing


    【解决方案1】:

    因为日志记录配置是全局的,为了正确使用日志记录功能,您必须正确配置日志记录。在您的特定情况下,没有在根级别配置处理程序,并且您没有为self.log 配置处理程序,因此不会发出任何日志消息(只是“找不到记录器“mycode”的处理程序)。此消息旨在表明日志配置存在错误,因为您的日志树如下所示:

    <--""
       Level WARNING
       |
       o<--"mycode"
           Level NOTSET so inherits level WARNING
    

    由于您没有处理程序,因此不会对您的 log.error 消息执行任何操作,并且在 unittestpy.test 下运行时不会执行您的代码。

    nose 默认情况下会在根级别添加日志捕获处理程序,因此最终的日志记录配置已正确配置,并且您的 log.error 代码将正确执行。

    快速解决方法是在 ClassThatLogsBadly 的代码顶部添加 logging.basicConfig() 或在初始化时向 log 类成员添加适当的处理程序。这样, unittest 和 py.test 都会捕获它。

    最后,你真的不应该在记录器之外格式化你的东西:如果没有配置级别,你根本不应该进行格式化,而只是跳过整个记录加速执行。

    【讨论】:

    • 您能再详细说明一下吗?我在我的类中定义了一个 basicConfig 并捕获了处理程序,并且在测试 Logger 类时,鼻子的错误仍然存​​在(测试使用 Pydev 测试和正常的 unittest 运行)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多