我強烈建議使用從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