在Python中从单元测试输出数据
如果我在用Python写单元测试(使用unittest模块),我能否在测试失败时输出一些数据,这样我就可以检查这些数据,帮助我找出错误的原因?
我知道可以创建一个自定义的消息,里面可以包含一些信息,但有时候你可能会处理更复杂的数据,这些数据不容易用字符串表示。
比如,假设你有一个叫Foo的类,并且在测试一个叫bar的方法,使用的数据来自一个叫testdata的列表:
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
如果测试失败了,我可能想输出t1、t2和/或f,看看为什么这些特定的数据导致了失败。这里的输出是指,在测试运行后,这些变量可以像其他变量一样被访问。
14 个回答
34
你可以使用简单的打印语句,或者其他任何方式来输出信息到标准输出。你也可以在测试的任何地方调用Python调试器。
如果你使用 nose 来运行你的测试(我推荐这样做),它会收集每个测试的标准输出,只有在测试失败时才会显示给你,这样在测试通过时你就不会看到杂乱的输出了。
nose 还有一些选项,可以自动显示在断言中提到的变量,或者在测试失败时调用调试器。例如,-s
(--nocapture
) 这个选项可以防止捕获标准输出。
84
在Python 2.7中,你可以使用一个额外的参数,msg
,来给错误信息添加一些说明,像这样:
self.assertEqual(f.bar(t2), 2, msg='{0}, {1}'.format(t1, t2))
官方文档可以在这里找到。
85
我们使用日志模块来实现这个功能。
比如说:
import logging
class SomeTest( unittest.TestCase ):
def testSomething( self ):
log= logging.getLogger( "SomeTest.testSomething" )
log.debug( "this= %r", self.this )
log.debug( "that= %r", self.that )
self.assertEqual( 3.14, pi )
if __name__ == "__main__":
logging.basicConfig( stream=sys.stderr )
logging.getLogger( "SomeTest.testSomething" ).setLevel( logging.DEBUG )
unittest.main()
这样我们就可以为一些特定的测试打开调试功能,这些测试我们知道是失败的,并且我们想要更多的调试信息来帮助我们找出问题。
不过,我更喜欢的方法不是花很多时间在调试上,而是花时间写更详细的测试,以便更好地发现问题。