You are here: Partenza > Dive Into Python > Test delle unità di codice > Verificare i casi di errore | << >> | ||||
Dive Into PythonPython per programmatori esperti |
Non è abbastanza verificare che la nostra funzione abbia successo quando gli input sono validi; occorre anche verificare che la funzione vada in errore quando riceve input non validi. E non basta che vada in errore: deve farlo nel modo che ci si aspetta.
Ricordiamoci di due altri requisiti per toRoman:
In Python, le funzioni indicano gli errori sollevando eccezioni, ed il modulo unittest fornisce metodi per verificare se una funzione solleva una particolare eccezione quando riceve un input non valido.
class ToRomanBadInput(unittest.TestCase): def testTooLarge(self): """toRoman should fail with large input""" self.assertRaises(roman.OutOfRangeError, roman.toRoman, 4000) def testZero(self): """toRoman should fail with 0 input""" self.assertRaises(roman.OutOfRangeError, roman.toRoman, 0) def testNegative(self): """toRoman should fail with negative input""" self.assertRaises(roman.OutOfRangeError, roman.toRoman, -1) def testDecimal(self): """toRoman should fail with non-integer input""" self.assertRaises(roman.NotIntegerError, roman.toRoman, 0.5)
La classe TestCase del modulo unittest fornisce il metodo assertRaises, che accetta i seguenti argomenti: l'eccezione attesa, la funzione sotto test e gli argomenti da passare alla funzione. Se la funzione sotto test richiede più di un argomento, passateli nell'ordine giusto al metodo assertRaises e questi li passerà a sua volta nello stesso ordine alla funzione da verificare. Fate attenzione a quello che si sta facendo a questo punto: invece di chiamare direttamente toRoman e verificare manualmente che sollevi una particolare eccezione (incapsulandola in un blocco try...except), il metodo assertRaises si incarica al posto nostro di chiamare toRoman con il suo argomento (4000) e si assicura che sollevi l'eccezione roman.OutOfRangeError. Ho ricordato di recente com'è comodo che tutto in Python sia un oggetto, incluse funzioni ed eccezioni? | |
Oltre ad effettuare test con numeri troppo grandi, abbiamo bisogno di fare test con numeri troppo piccoli. Ricordiamoci che i numeri romani non possono esprimere lo zero o quantità negative, per cui è opportuno predisporre dei test per questi casi (testZero e testNegative). In testZero, si sta verificando che toRoman sollevi un'eccezione roman.OutOfRangeError quando è chiamata con 0; se non solleva tale eccezione (sia che restituisca un valore o che sollevi un'eccezione diversa), il test è considerato fallito. | |
Il requisito #3 specifica che la funzione toRoman non può accettare un numero decimale, perciò in questo punto si sta verificando che la funzione toRoman sollevi un'eccezione roman.NotIntegerError quando chiamata con un parametro decimale (0.5). Se la funzione toRoman non solleva un eccezione roman.NotIntegerError, questo test è considerato fallito. |
I prossimi due requisiti sono simili ai primi tre, fatta eccezione per il fatto che si applicano a fromRoman invece che a toRoman.
IL requisito #4 è gestito nello stesso modo del requisito #1, iterando attraverso un campione di valori noti ed effettuando una verifica con ciascuno di essi. Il requisito #5 è gestito alla stessa maniera dei requisiti #2 e #3, verificando la funzione con una serie di input non validi e controllando che sollevi le opportune eccezioni.
class FromRomanBadInput(unittest.TestCase): def testTooManyRepeatedNumerals(self): """fromRoman should fail with too many repeated numerals""" for s in ('MMMM', 'DD', 'CCCC', 'LL', 'XXXX', 'VV', 'IIII'): self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s) def testRepeatedPairs(self): """fromRoman should fail with repeated pairs of numerals""" for s in ('CMCM', 'CDCD', 'XCXC', 'XLXL', 'IXIX', 'IVIV'): self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s) def testMalformedAntecedent(self): """fromRoman should fail with malformed antecedents""" for s in ('IIMXCC', 'VX', 'DCM', 'CMM', 'IXIV', 'MCMC', 'XCX', 'IVI', 'LM', 'LD', 'LC'): self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s)
<< Verificare i casi di successo |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
Verificare la consistenza >> |