5.3.1 Un semplice esempio

Il modulo unittest fornisce un ricco insieme di strumenti per costruire ed eseguire dei test. Questa sezione mostra come un piccolo sotto insieme di tali strumenti sia sufficiente a venire incontro alle necessità della maggior parte degli utenti.

Ecco un breve script per testare tre funzioni del modulo random:

import random
import unittest

class TestSequenceFunctions(unittest.TestCase):
    
    def setUp(self):
        self.seq = range(10)

    def testshuffle(self):
        # assicura che la sequenza rimescolata non perda degli elementi
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, range(10))

    def testchoice(self):
        element = random.choice(self.seq)
        self.assert_(element in self.seq)

    def testsample(self):
        self.assertRaises(ValueError, random.sample, self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assert_(element in self.seq)

if __name__ == '__main__':
    unittest.main()

Una testcase viene creata derivandola da una classe unittest.TestCase. I tre test singoli sono definiti tramite dei metodi il cui nome inizia con le lettere "test". Questa convenzione sul nome informa il test runner di quali sono i metodi che rappresentano dei test.

Il punto cruciale di ogni test è una chiamata ad assertEqual() per controllare l'esattezza del risultato; al metodo assert_() per verificare una condizione, oppure ad assertRaises() per verificare che un'eccezione venga sollevata come ci si aspetta. Questi metodi sono usati in luogo di un'istruzione assert così che il test runner possa accumulare tutti i risultati dei vari metodi e produrre un resoconto finale.

Quando viene definito un metodo setUp(), il test runner avvierà questo metodo prima di ogni test. Allo stesso modo, se viene definito un metodo tearDown(), il test runner invocherà tale metodo dopo l'esecuzione di ogni test. Nell'esempio precedente, setUp() veniva usato per creare, per ogni test, una nuova sequenza.

Il blocco finale mostra un modo semplice per eseguire i test. unittest.main() mette a disposizione un'interfaccia a riga di comando per testare lo script. Quando viene eseguito da riga di comando, lo script precedente produce un output di questo tipo:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Invece di unittest.main(), esistono altri modi per eseguire i test con un livello di controllo più raffinato, un output meno conciso e senza la necessità di eseguirli da riga di comando. Per esempio, le ultime due righe possono essere sostituite con:

suite = unittest.makeSuite(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)

Eseguendo il nuovo script dall'interprete o da un altro script, si ottiene il seguente output:

testchoice (__main__.TestSequenceFunctions) ... ok
testsample (__main__.TestSequenceFunctions) ... ok
testshuffle (__main__.TestSequenceFunctions) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.110s

OK

Gli esempi precedenti mostrano le funzionalità più comunemente usate di unittest, sufficienti ai bisogni di tutti i giorni. Il resto della documentazione approfondisce l'insieme completo delle funzionalità a partire dai principi di base.

Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.