我强烈建议使用从nose.tools
assert_raises
和assert_raises_regexp
,其中重复的assertRaises
和unittest.TestCase
assertRaisesRegexp
行为。这些允许在测试套件中使用与unittest.TestCase
提供的功能相同的功能,但实际上并不使用unittest.TestCase
类。
我发现@raises
是太钝的仪器。下面是代码说明问题:
from nose.tools import *
something = ["aaa", "bbb"]
def foo(x, source=None):
if source is None:
source = something
return source[x]
# This is fine
@raises(IndexError)
def test1():
foo(3)
# This is fine. The expected error does not happen because we made
# a mistake in the test or in the code. The failure indicates we made
# a mistake.
@raises(IndexError)
def test2():
foo(1)
# This passes for the wrong reasons.
@raises(IndexError)
def test3():
source = something[2] # This is the line that raises the exception.
foo(10, source) # This is not tested.
# When we use assert_raises, we can isolate the line where we expect
# the failure. This causes an error due to the exception raised in
# the first line of the function.
def test4():
source = something[2]
with assert_raises(IndexError):
foo(10, source)
test3
通行证,但不是因为foo
已经提出了我们预期的异常,但因为设置了数据的代码由foo
使用失败,同样的异常。test4
显示了如何使用assert_raises
来编写测试来实际测试我们要测试的含义。第一行的问题会导致Nose报告一个错误,然后我们可以重写测试,以便最终测试我们的测试意图。
@raises
不允许测试与异常相关的消息。当我提出ValueError
时,我只是想举一个例子,我通常想提出一个信息性的消息。这里有一个例子:
def bar(arg):
if arg: # This is incorrect code.
raise ValueError("arg should be higher than 3")
if arg >= 10:
raise ValueError("arg should be less than 10")
# We don't know which of the possible `raise` statements was reached.
@raises(ValueError)
def test5():
bar(10)
# Yes, we're getting an exception but with the wrong value: bug found!
def test6():
with assert_raises_regexp(ValueError, "arg should be less than 10"):
bar(10)
test5
它采用@raises
会过去,但它会通过对错误的原因。 test6
执行更精细的测试,显示ValueError
提出的不是我们想要的。
差不多一个副本http://stackoverflow.com/questions/11767938/how-to-use-noses-assert-raises – Stefano