Vai al contenuto principale

Tutorial sul unit testing in Python

Scopri cos’è il unit testing, perché è importante e come implementarlo in Python.
Aggiornato 29 set 2026  · 10 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Il unit testing è un metodo di collaudo software in cui singole unità del codice sorgente vengono sottoposte a vari test per stabilire se sono pronte all’uso. Serve a determinare e garantire la qualità del tuo codice.

In genere, una volta terminato lo sviluppo, lo sviluppatore inserisce nel test script dei criteri o dei risultati che si presume siano pratici e utili per verificare la correttezza di una particolare unità. Durante l’esecuzione dei casi di test, vari framework registrano i test che non soddisfano un criterio e li riportano in un riepilogo.

Ci si aspetta che gli sviluppatori scrivano script di test automatizzati, in modo da garantire che ogni sezione o unità rispetti il proprio design e si comporti come previsto.

Unit testing in Python

Anche se scrivere test manuali per il tuo codice è sicuramente un’attività noiosa e dispendiosa in termini di tempo, il framework di unit testing integrato in Python ha reso la vita molto più semplice.

Il framework per il unit testing in Python si chiama unittest ed è incluso in Python.

Il unit testing rende il tuo codice a prova di futuro, perché ti porta ad anticipare i casi in cui potrebbe fallire o generare un bug. Anche se non puoi prevederli tutti, riesci comunque a coprirne la maggior parte.

Un’unità può rientrare in varie categorie:

  • Un intero modulo,
  • Una singola funzione,
  • Un’interfaccia completa come una classe o un metodo.

Il modo migliore per scrivere unit test è iniziare dall’unità più piccola testabile che il tuo codice possa avere, poi passare alle altre unità e vedere come quella più piccola interagisce con le altre. In questo modo puoi costruire una suite di unit test completa per le tue applicazioni.

Il framework di unit testing di Python è stato ispirato da JUnit di Java e ha funzionalità simili ai principali framework di unit testing in altri linguaggi. Il framework di unit testing di Python offre varie funzionalità, tra cui:

  • Automazione dei test
  • Condivisione del codice di setup e teardown per i test
  • Aggregazione dei test in raccolte
  • Indipendenza dei test dal framework di reportistica

Ora vediamo un esempio per capire perché hai bisogno di fare unit testing del tuo codice.

Primi passi con unittest di Python

Di seguito, abbiamo illustrato i passaggi necessari per usare il framework unittest di Python

Creare una funzione per il cubo

Scriviamo un codice per calcolare il volume di un cubo in Python

def cuboid_volume(l):
    return (l*l*l)
length = [2,1.1, -2.5, 2j, 'two']
for i in range(len(length)):
    print ("The volume of cuboid:",cuboid_volume(length[i]))
The volume of cuboid: 8
The volume of cuboid: 1.3310000000000004
The volume of cuboid: -15.625
The volume of cuboid: (-0-8j)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-67e1c37a435f> in <module>
      1 for i in range(len(length)):
----> 2     print ("The volume of cuboid:",cuboid_volume(length[i]))
<ipython-input-2-f50464fd88da> in cuboid_volume(l)
      1 def cuboid_volume(l):
----> 2     return (l*l*l)
TypeError: can't multiply sequence by non-int of type 'str'

Analisi dei risultati

L’output sopra dovrebbe darti un’idea dell’importanza di avere un unit test per il tuo codice. Ci sono tre cose decisamente sbagliate nel codice qui sopra:

  • Primo, il volume del parallelepipedo è negativo,
  • Secondo, il volume del parallelepipedo è un numero complesso,
  • Infine, il codice genera un TypeError perché non puoi moltiplicare una stringa, che non è un int.

Per fortuna il terzo problema ha prodotto un errore, mentre il primo e il secondo sono comunque riusciti anche se il volume del parallelepipedo non può essere negativo né un numero complesso.

Gli unit test di solito si scrivono come codice separato in un file diverso e puoi seguire diverse convenzioni di denominazione. Puoi dare al file degli unit test il nome del codice/unità + test separati da un underscore, oppure test + nome del codice/unità separati da un underscore.

Per esempio, se il nome del file di codice sopra è cuboid_volume.py, allora il nome del file degli unit test potrebbe essere cuboid_volume_test.py

Senza ulteriori indugi, scriviamo l’unit test per il codice sopra.

Uso di assertAlmostEqual

Per prima cosa, creiamo un file Python chiamato volume_cuboid.py, che conterrà il codice per calcolare il volume, e un secondo file chiamato test_volume_cuboid.py, che conterrà il codice dell’unit test.

importa unittest

La classe TestCuboid eredita dal modulo unittest e, in questa classe, definisci i vari metodi con cui vuoi che l’unit test verifichi la tua funzione cuboid_volume.

La prima funzione che definirai è test_volume, che verifica se l’output restituito da cuboid_volume è uguale a quello che ti aspetti. Per farlo, userai il metodo assertAlmostEqual.

Test 1

class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),0)
        self.assertAlmostEqual(cuboid_volume(5.5),166.375)

code 1

code 2

Eseguiamo lo script sopra. Eseguirai il modulo unittest come script specificando -m durante l’esecuzione.

!python -m unittest test_volume_cuboid.py

Output:

.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK

Ottimo! Il tuo primo unit test funziona.

Il test è stato eseguito correttamente e ha restituito OK, il che significa che la funzione cuboid_volume funziona come ti aspetti.

Test 2

Vediamo cosa succede quando uno dei metodi assertAlmostEqual fallisce.

code 3

Nota che l’ultima istruzione assert è stata modificata.

!python -m unittest test_volume_cuboid.py

Output:

F
======================================================================
FAIL: test_volume (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 15, in test_volume
    self.assertAlmostEqual(cuboid_volume(5.5),0)
AssertionError: 166.375 != 0 within 7 places (166.375 difference)
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)

Dall’output sopra, puoi osservare che l’ultima istruzione assert ha generato un AssertionError e quindi un fallimento del test. Il modulo di unit testing di Python mostra il motivo del fallimento, insieme al numero di errori nel tuo codice.

Uso di assertRaises

Ora esploriamo un altro metodo assert, cioè assertRaises, che ti aiuterà a capire se la tua funzione cuboid_volume gestisce correttamente i valori di input.

Diciamo che vuoi verificare se la tua funzione cuboid_volume gestisce la classe o il tipo dell’input; ad esempio, se passi una stringa come input, la gestirà come eccezione o con una condizione if, dato che la lunghezza del parallelepipedo non potrà mai essere una stringa.

code 4

!python -m unittest test_volume_cuboid.py

Output:

F.
======================================================================
FAIL: test_input_value (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 17, in test_input_value
    self.assertRaises(TypeError, cuboid_volume, True)
AssertionError: TypeError not raised by cuboid_volume
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)

Perfetto! Dall’output sopra è evidente che il tuo codice volume_cuboid.py non gestisce correttamente l’input che gli viene passato.

Modificare la funzione del cubo

Aggiungiamo una condizione in volume_cuboid.py per verificare se l’input, cioè la lunghezza del parallelepipedo, è un booleano o una stringa e, in tal caso, sollevare un errore.

code 5

!python -m unittest test_volume_cuboid.py

Output:

..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK

Eseguire lo script di test Python in JupyterLab

Ora eseguiamo lo script di test all’interno di JupyterLab. Per farlo, per prima cosa definirai lo script di test in JupyterLab, come mostrato di seguito.

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),1)
    def test_input_value(self):
        self.assertRaises(TypeError, cuboid_volume, True)

Poi userai il metodo unittest.main() per eseguire lo script di test. Puoi passare diversi argomenti al metodo seguente, tra cui uno è il livello di verbosità.

Facciamo qualche esperimento con diversi livelli di verbosità e vediamo come cambia la descrizione dell’output.

Verbosità 0

unittest.main(argv=[''],verbosity=0, exit=False)
Output:
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
<unittest.main.TestProgram at 0x1de02774348>

Verbosità 1

unittest.main(argv=[''],verbosity=1, exit=False)
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a1cc8>

Verbosità 2

unittest.main(argv=[''],verbosity=2, exit=False)
Output:
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a8308>

Visualizzare l’AssertionError

Infine, modifichiamo l’ultimo assertAlmostEqual nel metodo test_volume e analizziamo come il livello di verbosità 2 mostrerà il fallimento del metodo.

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),1)
    def test_input_value(self):
        self.assertRaises(TypeError, cuboid_volume, True)
unittest.main(argv=[''],verbosity=2, exit=False)

Output:

test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... FAIL
======================================================================
FAIL: test_volume (__main__.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-28-46ad33b909ee>", line 14, in test_volume
    self.assertAlmostEqual(cuboid_volume(0),1)
AssertionError: 0 != 1 within 7 places (1 difference)
----------------------------------------------------------------------
Ran 2 tests in 0.003s
FAILED (failures=1)
<unittest.main.TestProgram at 0x1de027b5448>

Riepilogo

Dagli output sopra si possono trarre le seguenti conclusioni:

  • Il livello di verbosità 0 mostra solo quanti test sono stati eseguiti, cioè 2, insieme al tempo impiegato,
  • Il livello di verbosità 1 aggiunge due punti .. che indicano che sono stati eseguiti due test,
  • Il livello di verbosità 2 mostra i nomi dettagliati dei metodi eseguiti insieme al loro stato OK o FAIL.

Metodi Assert disponibili in unittest

Nel modulo di unit testing di Python ci sono molti metodi assert che puoi sfruttare per i tuoi test.

Metodi assert usati più spesso

Metodi assert usati più spesso

Fonte: documentazione di unittest

 Controlli di produzione

Usando i seguenti metodi, puoi verificare la produzione di eccezioni, avvertimenti e messaggi di log.

Controlli di produzione

Fonte: documentazione di unittest

 Metodi specifici per attività

Metodi specifici per attività

Fonte: documentazione di unittest

 

Per conoscere in dettaglio i metodi assert, consulta la documentazione ufficiale di Python.

Puoi anche informarti tramite il modulo Pydoc, simile alla funzione help in Python. Di seguito una dimostrazione di come usare Pydoc per leggere la documentazione del metodo assertCountEqual.

!python -m pydoc unittest.TestCase.assertCountEqual

Output:

Help on function assertCountEqual in unittest.TestCase:
unittest.TestCase.assertCountEqual = assertCountEqual(self, first, second, msg=None)
    An unordered sequence comparison asserting that the same elements,
    regardless of order.  If the same element occurs more than once,
    it verifies that the elements occur the same number of times.
        self.assertEqual(Counter(list(first)),
                         Counter(list(second)))
     Example:
        - [0, 1, 1] and [1, 0, 1] compare equal.
        - [0, 0, 1] and [0, 1] compare unequal.

Conclusione

Questo tutorial è stata un’introduzione di base al unit testing in Python e alla sua importanza per uno sviluppatore. Un buon esercizio per te sarebbe scrivere un modulo di test per uno dei tuoi progetti passati. Ti darà un’ottima esperienza pratica nella scrittura di unit test. Prova anche a esplorare gli altri metodi Assert. Puoi approfondire il unit testing con il nostro tutorial su Pytest. 

Se stai iniziando con Python e vuoi saperne di più, segui il nostro corso Introduzione alla Data Science in Python.


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.

Argomenti
Python

Scopri di più su Python con questi corsi!

Corso

Introduzione a Python

4 ore
7.1M
Impara le basi dell’analisi dei dati con Python in sole 4 ore. Questo corso online ti introduce all’interfaccia di Python e ai pacchetti più usati.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

Mostra AltroMostra Altro