7.3. Verificare i casi di successo

La parte fondamentale della verifica delle unità di codice è costruire i singoli test. Un test risponde ad una singola domanda sul codice che si sta verificando.

Un singolo test dovrebbe essere capace di ...

Detto tutto questo, costruiamo il nostro primo test. Abbiamo il seguente requisito:

  1. La funzione toRoman dovrebbe restituire la rappresentazione in numeri romani di qualsiasi numero arabo da 1 a 3999.

Esempio 7.2. testToRomanKnownValues


class KnownValues(unittest.TestCase):                           1
    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'))                        2

    def testToRomanKnownValues(self):                           3
        """toRoman should give known result with known input"""
        for integer, numeral in self.knownValues:              
            result = roman.toRoman(integer)                     4 5
            self.assertEqual(numeral, result)                   6
1 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.
2 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.
3 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.
4 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.
5 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.
6 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.