vi consiglio vivamente di utilizzare assert_raises
e assert_raises_regexp
da nose.tools
, che riprodurre il comportamento di assertRaises
e assertRaisesRegexp
da unittest.TestCase
. Questi consentono di utilizzare la stessa funzionalità fornita da unittest.TestCase
in suite di test che non utilizzano effettivamente la classe unittest.TestCase
.
Trovo che lo @raises
sia uno strumento troppo smussato. Qui è il codice che illustra il problema:
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
passaggi, ma non perché foo
ha sollevato l'eccezione che ci aspettavamo, ma perché il codice che imposta i dati per essere utilizzati da foo
non riesce con la stessa eccezione.test4
mostra come il test può essere scritto usando assert_raises
per testare realmente ciò che intendiamo testare. Il problema sulla prima riga causerà a Nose di segnalare un errore e quindi potremo riscrivere il test in modo tale da poter finalmente testare ciò che intendevamo testare.
@raises
non consente di testare il messaggio associato all'eccezione. Quando sollevo ValueError
, solo per fare un esempio, di solito voglio sollevarlo con un messaggio informativo. Ecco un esempio:
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
che utilizza @raises
passerà, ma passerà per la ragione sbagliata. test6
esegue un test più accurato che rivela che lo ValueError
generato non era quello che volevamo.
quasi un doppio di http://stackoverflow.com/questions/11767938/how-to-use-noses-assert-raises – Stefano