Sil*_*ish 108 python unit-testing
如果我在python中编写单元测试(使用unittest模块),是否可以从失败的测试中输出数据,所以我可以检查它以帮助推断导致错误的原因?我知道能够创建自定义消息,它可以携带一些信息,但有时您可能会处理更复杂的数据,这些数据不能轻易地表示为字符串.
例如,假设您有一个类Foo,并使用名为testdata的列表中的数据测试方法栏:
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
Run Code Online (Sandbox Code Playgroud)
如果测试失败,我可能想输出t1,t2和/或f,以查看此特定数据导致失败的原因.通过输出,我的意思是在运行测试之后,可以像任何其他变量一样访问变量.
Fac*_*sco 70
对于像我这样的人来到这里寻找一个简单快速的答案的人来说,这是一个很晚的答案.
在Python 2.7中,您可以使用其他参数msg
向错误消息添加信息,如下所示:
self.assertEqual(f.bar(t2), 2, msg='{0}, {1}'.format(t1, t2))
Run Code Online (Sandbox Code Playgroud)
官方文档在这里
S.L*_*ott 68
我们使用日志记录模块.
例如:
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 )
# etc.
self.assertEquals( 3.14, pi )
if __name__ == "__main__":
logging.basicConfig( stream=sys.stderr )
logging.getLogger( "SomeTest.testSomething" ).setLevel( logging.DEBUG )
unittest.main()
Run Code Online (Sandbox Code Playgroud)
这允许我们打开我们知道失败的特定测试的调试,并且我们需要额外的调试信息.
但是,我首选的方法是不要花费大量时间进行调试,而是花费大量时间编写更精细的测试来揭示问题.
mon*_*kut 16
我认为这不是你想要的,没有办法显示不会失败的变量值,但这可能会帮助你更接近按照你想要的方式输出结果.
您可以使用TestRunner.run()返回的TestResult对象进行结果分析和处理.特别是TestResult.errors和TestResult.failures
关于TestResults对象:
http://docs.python.org/library/unittest.html#id3
还有一些代码可以指出你正确的方向:
>>> import random
>>> import unittest
>>>
>>> class TestSequenceFunctions(unittest.TestCase):
... def setUp(self):
... self.seq = range(5)
... def testshuffle(self):
... # make sure the shuffled sequence does not lose any elements
... random.shuffle(self.seq)
... self.seq.sort()
... self.assertEqual(self.seq, range(10))
... def testchoice(self):
... element = random.choice(self.seq)
... error_test = 1/0
... self.assert_(element in self.seq)
... def testsample(self):
... self.assertRaises(ValueError, random.sample, self.seq, 20)
... for element in random.sample(self.seq, 5):
... self.assert_(element in self.seq)
...
>>> suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
>>> testResult = unittest.TextTestRunner(verbosity=2).run(suite)
testchoice (__main__.TestSequenceFunctions) ... ERROR
testsample (__main__.TestSequenceFunctions) ... ok
testshuffle (__main__.TestSequenceFunctions) ... FAIL
======================================================================
ERROR: testchoice (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 11, in testchoice
ZeroDivisionError: integer division or modulo by zero
======================================================================
FAIL: testshuffle (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 8, in testshuffle
AssertionError: [0, 1, 2, 3, 4] != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
----------------------------------------------------------------------
Ran 3 tests in 0.031s
FAILED (failures=1, errors=1)
>>>
>>> testResult.errors
[(<__main__.TestSequenceFunctions testMethod=testchoice>, 'Traceback (most recent call last):\n File "<stdin>"
, line 11, in testchoice\nZeroDivisionError: integer division or modulo by zero\n')]
>>>
>>> testResult.failures
[(<__main__.TestSequenceFunctions testMethod=testshuffle>, 'Traceback (most recent call last):\n File "<stdin>
", line 8, in testshuffle\nAssertionError: [0, 1, 2, 3, 4] != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n')]
>>>
Run Code Online (Sandbox Code Playgroud)
我想我可能一直在思考这个问题.我提出的一种方法就是完成工作,只需要一个全局变量来累积诊断数据.
像这样的东西:
log1 = dict()
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
if f.bar(t2) != 2:
log1("TestBar.runTest") = (f, t1, t2)
self.fail("f.bar(t2) != 2")
Run Code Online (Sandbox Code Playgroud)
谢谢你的回复.他们给了我一些关于如何记录单元测试信息的替代方法.
另一种选择 - 启动测试失败的调试器.
尝试使用Testoob运行测试(它将运行您的unittest套件而不进行更改),并且您可以使用'--debug'命令行开关在测试失败时打开调试器.
这是windows上的终端会话:
C:\work> testoob tests.py --debug
F
Debugging for failure in test: test_foo (tests.MyTests.test_foo)
> c:\python25\lib\unittest.py(334)failUnlessEqual()
-> (msg or '%r != %r' % (first, second))
(Pdb) up
> c:\work\tests.py(6)test_foo()
-> self.assertEqual(x, y)
(Pdb) l
1 from unittest import TestCase
2 class MyTests(TestCase):
3 def test_foo(self):
4 x = 1
5 y = 2
6 -> self.assertEqual(x, y)
[EOF]
(Pdb)
Run Code Online (Sandbox Code Playgroud)
我使用的方法非常简单.我只是将其记录为警告,以便它实际显示出来.
import logging
class TestBar(unittest.TestCase):
def runTest(self):
#this line is important
logging.basicConfig()
log = logging.getLogger("LOG")
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
log.warning(t1)
Run Code Online (Sandbox Code Playgroud)
在这些情况下,我log.debug()
在我的应用程序中使用了一些消息。由于默认日志级别为WARNING
,因此在正常执行中不会显示此类消息。
然后,在单元测试中,我将日志记录级别更改为DEBUG
,以便在运行它们时显示此类消息。
import logging
log.debug("Some messages to be shown just when debugging or unit testing")
Run Code Online (Sandbox Code Playgroud)
在单元测试中:
# Set log level
loglevel = logging.DEBUG
logging.basicConfig(level=loglevel)
Run Code Online (Sandbox Code Playgroud)
查看完整示例:
这是daikiri.py
一个基本类,它实现一个daikiri其名称和价格。有一种方法make_discount()
可以在应用给定的折扣后返回该特定代基里的价格:
import logging
log = logging.getLogger(__name__)
class Daikiri(object):
def __init__(self, name, price):
self.name = name
self.price = price
def make_discount(self, percentage):
log.debug("Deducting discount...") # I want to see this message
return self.price * percentage
Run Code Online (Sandbox Code Playgroud)
然后,我创建了一个单元测试test_daikiri.py
,来检查它的使用情况:
import unittest
import logging
from .daikiri import Daikiri
class TestDaikiri(unittest.TestCase):
def setUp(self):
# Changing log level to DEBUG
loglevel = logging.DEBUG
logging.basicConfig(level=loglevel)
self.mydaikiri = Daikiri("cuban", 25)
def test_drop_price(self):
new_price = self.mydaikiri.make_discount(0)
self.assertEqual(new_price, 0)
if __name__ == "__main__":
unittest.main()
Run Code Online (Sandbox Code Playgroud)
因此,当我执行它时,我收到log.debug
消息:
$ python -m test_daikiri
DEBUG:daikiri:Deducting discount...
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
100479 次 |
最近记录: |