我们看到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
要填充的有效插槽(类型为),因此无法执行。这是一个已知的问题,解决方案是在记录器外部格式化您的内容。但是,我们的问题是进行测试以确保做到这一点。
针对使用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)
由于日志记录配置是全局的,因此为了正确地行使日志记录功能,您必须正确配置日志记录。在您的特定情况下,没有在根级别配置任何处理程序,也没有为配置任何处理程序self.log
,因此将不会发出任何日志消息(只是“找不到针对记录程序“ mycode”的处理程序”)。旨在指示日志记录配置中存在错误,因为您的日志树如下所示:
<--""
Level WARNING
|
o<--"mycode"
Level NOTSET so inherits level WARNING
由于您没有处理程序,因此您的log.error
消息不会做任何事情,并且在unittest
或下运行时,代码不会被执行py.test
。
nose
默认情况下,在根级别添加日志捕获处理程序,因此正确配置了最终的日志记录配置,并且log.error
正确执行了代码。
一个快速的解决方法是在初始化时logging.basicConfig()
在代码之上添加ClassThatLogsBadly
或向log
类成员添加适当的处理程序。这样,unittest和py.test都可以捕获它。
最后,您实际上不应该在记录器之外格式化您的内容:如果未配置级别,则根本不应该进行格式化,而只是跳过整个日志记录以加快执行速度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句