Un singolo test dovrebbe essere capace di ...
Detto tutto questo, costruiamo il nostro primo test.
Abbiamo il seguente
requisito:
Esempio 7.2. testToRomanKnownValues
class KnownValues(unittest.TestCase):
knownValues = ( (1, 'I'),
(2, 'II'),
(3, 'III'),
(4, 'IV'),
(5, 'V'),
(6, 'VI'),
(7, 'VII'),
(8, 'VIII'),
(9, 'IX'),
(10, 'X'),
(50, 'L'),
(100, 'C'),
(500, 'D'),
(1000, 'M'),
(31, 'XXXI'),
(148, 'CXLVIII'),
(294, 'CCXCIV'),
(312, 'CCCXII'),
(421, 'CDXXI'),
(528, 'DXXVIII'),
(621, 'DCXXI'),
(782, 'DCCLXXXII'),
(870, 'DCCCLXX'),
(941, 'CMXLI'),
(1043, 'MXLIII'),
(1110, 'MCX'),
(1226, 'MCCXXVI'),
(1301, 'MCCCI'),
(1485, 'MCDLXXXV'),
(1509, 'MDIX'),
(1607, 'MDCVII'),
(1754, 'MDCCLIV'),
(1832, 'MDCCCXXXII'),
(1993, 'MCMXCIII'),
(2074, 'MMLXXIV'),
(2152, 'MMCLII'),
(2212, 'MMCCXII'),
(2343, 'MMCCCXLIII'),
(2499, 'MMCDXCIX'),
(2574, 'MMDLXXIV'),
(2646, 'MMDCXLVI'),
(2723, 'MMDCCXXIII'),
(2892, 'MMDCCCXCII'),
(2975, 'MMCMLXXV'),
(3051, 'MMMLI'),
(3185, 'MMMCLXXXV'),
(3250, 'MMMCCL'),
(3313, 'MMMCCCXIII'),
(3408, 'MMMCDVIII'),
(3501, 'MMMDI'),
(3610, 'MMMDCX'),
(3743, 'MMMDCCXLIII'),
(3844, 'MMMDCCCXLIV'),
(3888, 'MMMDCCCLXXXVIII'),
(3940, 'MMMCMXL'),
(3999, 'MMMCMXCIX'))
def testToRomanKnownValues(self):
"""toRoman should give known result with known input"""
for integer, numeral in self.knownValues:
result = roman.toRoman(integer)
self.assertEqual(numeral, result)
|
Per scrivere un test, occorre per prima cosa specializzare la
classe TestCase del modulo unittest.
Questa classe fornisce molti utili metodi che si possono usare
nei test per verificare condizioni specifiche.
|
|
Questa è una lista di coppie numeri di interi/numeri romani
che ho verificato manualmente. Comprende i dieci numeri più
bassi, i dieci numeri più alti, tutti i numeri arabi che si
traducono in un numero romano con singolo carattere. Il
concetto di un test delle unità di codice non è quello di
verificare ogni possibile input, ma di verificare un campione
rappresentativo.
|
|
Ogni test individuale consiste in un metodo dedicato, che non
deve accettare parametri né restituire valori. Se il metodo
termina senza sollevare eccezioni, il test ha avuto successo;
se il metodo solleva un'eccezione, il test è fallito.
|
|
Qui viene chiamata la funzione toRoman (beh, la funzione
non è stata ancora scritta, ma una volta pronta, questa
sarà la linea che la chiama). Da notare che ora abbiamo definito
l'interfaccia di programma (API) della funzione toRoman:
deve prendere in input un intero (il numero da convertire) e
deve restituire una stringa (la rappresentazione in numeri
romani). Se l'interfaccia della funzione risulta diversa da
questa, il test è considerato fallito.
|
|
Da notare anche che non si cerca di intercettare eventuali
eccezioni sollevate dalla chiamata, alla funzione toRoman.
Questo è intenzionale: toRoman non dovrebbe sollevare
eccezioni quando è chiamata con input valido, ed i valori
di input usati sono validi. Se la funzione toRoman solleva
un eccezione, il test è considerato fallito.
|
|
Assumendo che la funzione toRoman sia stata definita
correttamente, chiamata correttamente, abbia completato
con successo la sua esecuzione ed abbia restituito un valore,
l'ultimo passo è controllare se ha restituito il valore
giusto. Questa è un caso comune, per
cui la classe TestCase fornisce un metodo,
assertEqual, per controllare se due valori sono uguali.
Se il valore restituito dalla funzione toRoman
(result) non corrisponde al valore noto
che ci si aspetta (numeral), il metodo
assertEqual solleva un'eccezione ed il test fallisce.
Se i due valori sono uguali, assertEqual non fa nulla.
Se ogni valore restituito da toRoman corrisponde al valore
atteso, assertEqual non solleva mai eccezioni, per cui
testToRomanKnownValues alla fine termina
normalmente, il che significa che toRoman ha superato
questo test.
|