Quando scrivi codice in Python, è importante assicurarsi che il tuo codice funzioni come previsto. Uno dei migliori modi per farlo è utilizzare i test unitari, che ti aiutano a verificare se piccole parti (o unità) del tuo codice funzionano correttamente.
In questo articolo, impareremo come scrivere e eseguire test unitari efficaci in Python utilizzando PyTest, uno dei framework di test più popolari per Python.
Cosa sono i Test Unitari?
I test unitari sono piccoli e semplici test che si concentrano sul controllo di una singola funzione o di un piccolo pezzo di codice. Aiutano a garantire che il tuo codice funzioni come previsto e possono individuare bug precocemente.
I test unitari possono essere scritti per diverse parti del tuo codice, come funzioni, metodi e persino classi. Scrivendo test unitari, puoi testare il tuo codice senza eseguire l’intero programma.
Perché Usare PyTest?
PyTest è un framework di test popolare per Python che rende facile scrivere e eseguire test.
È semplice da usare e ha molte funzionalità utili come:
- Ti consente di scrivere casi di test semplici e chiari.
- Fornisce funzionalità avanzate come fixture, test parametrizzati e plugin.
- Funziona bene con altri strumenti e librerie di test.
- Genera risultati e report di test facili da leggere.
Configurare PyTest in Linux
Prima di iniziare a scrivere i test, dobbiamo installare PyTest. Se non hai PyTest installato, puoi installarlo utilizzando il gestore di pacchetti Python chiamato pip.
pip install pytest
Una volta che PyTest è installato, sei pronto per iniziare a scrivere test!
Scrivere il tuo primo test con PyTest
Iniziamo scrivendo una funzione semplice e poi scriviamo un test per essa.
Passo 1: Scrivere una funzione semplice
Prima di tutto, creiamo una funzione Python che vogliamo testare. Diciamo che abbiamo una funzione che somma due numeri:
# add.py def add(a, b): return a + b
Questa è una funzione semplice che prende due numeri a e b, li somma e restituisce il risultato.
Passo 2: Scrivere un test per la funzione
Ora, scriviamo un test per la funzione di somma. In PyTest, i test sono scritti in file separati, tipicamente chiamati test_*.py
per facilitare l’identificazione dei file di test.
Crea un nuovo file chiamato test_add.py
e scrivi il seguente codice di test:
# test_add.py from add import add def test_add_numbers(): assert add(2, 3) == 5 assert add(-1, 1) == 0 assert add(0, 0) == 0
Spiegazione del codice sopra:
- Importiamo la funzione
add
dal fileadd.py
. - Definiamo una funzione di test chiamata
test_add_numbers()
. In PyTest, una funzione di test dovrebbe iniziare con la parolatest_
. - All’interno della funzione di test, utilizziamo l’istruzione
assert
per verificare se il risultato della chiamata alla funzioneadd
corrisponde al valore atteso. Se la condizione nell’istruzioneassert
èTrue
, il test passa; altrimenti, fallisce.
Passo 3: Esegui il Test
Per eseguire il test, apri il terminale e naviga nella directory in cui si trova il tuo file test_add.py
e poi esegui il seguente comando:
pytest
PyTest troverà automaticamente tutti i file di test (quelli che iniziano con test_
) e eseguirà i test al loro interno. Se tutto funziona correttamente, dovresti vedere un output simile a questo:

Il punto (.)
indica che il test è passato. Se ci fossero stati problemi, PyTest mostrerebbe un messaggio di errore.
Scrivere Test Più Avanzati
Ora che sappiamo come scrivere ed eseguire un test di base, esploriamo alcune funzionalità più avanzate di PyTest.
Testare le Eccezioni Attese
A volte, vuoi testare se il tuo codice solleva le eccezioni corrette quando qualcosa va storto. Puoi farlo con la funzione pytest.raises()
.
Supponiamo di voler testare una funzione che divide due numeri. Vogliamo sollevare un’eccezione se il secondo numero è zero (per evitare errori di divisione per zero).
Ecco la funzione divide
:
# divide.py def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b
Ora, scriviamo un test per questa funzione che verifica se viene sollevato ValueError
quando cerchiamo di dividere per zero:
# test_divide.py from divide import divide import pytest def test_divide_numbers(): assert divide(10, 2) == 5 assert divide(-10, 2) == -5 assert divide(10, -2) == -5 def test_divide_by_zero(): with pytest.raises(ValueError): divide(10, 0)
Spiegazione del codice:
- Abbiamo aggiunto una nuova funzione di test chiamata
test_divide_by_zero()
. - All’interno di questa funzione, utilizziamo
pytest.raises(ValueError)
per verificare se viene sollevato unValueError
quando chiamiamo la funzione di divisione con zero come secondo argomento.
Esegui nuovamente i test con il comando pytest. Se tutto funziona correttamente, dovresti vedere questo output:

Utilizzo delle Fixture per Setup e Cleanup
In alcuni casi, potresti dover impostare determinate condizioni prima di eseguire i tuoi test o pulire dopo che i test sono stati completati. PyTest fornisce fixture per gestire questo.
Una fixture è una funzione che puoi utilizzare per impostare o smontare condizioni per i tuoi test. Le fixture sono spesso utilizzate per creare oggetti o connettersi a database necessari per i test.
Ecco un esempio di utilizzo di una fixture per impostare una directory temporanea per testare operazioni su file:
# test_file_operations.py import pytest import os @pytest.fixture def temporary_directory(): temp_dir = "temp_dir" os.mkdir(temp_dir) yield temp_dir # This is where the test will run os.rmdir(temp_dir) # Cleanup after the test def test_create_file(temporary_directory): file_path = os.path.join(temporary_directory, "test_file.txt") with open(file_path, "w") as f: f.write("Hello, world!") assert os.path.exists(file_path)
Spiegazione del codice:
- Definiamo una fixture chiamata
temporary_directory
che crea una directory temporanea prima del test e la elimina successivamente. - La funzione di test
test_create_file()
utilizza questa fixture per creare un file nella directory temporanea e verifica se il file esiste.
Esegui nuovamente i test con il comando pytest. PyTest rileverà automaticamente e utilizzerà la fixture.
Parametrizza i tuoi Test con Pytest
A volte, desideri eseguire lo stesso test con input diversi. PyTest ti consente di farlo facilmente utilizzando parametrize.
Supponiamo di voler testare la nostra funzione add
con diverse coppie di numeri. Invece di scrivere funzioni di test separate per ciascuna coppia, possiamo usare pytest.mark.parametrize
per eseguire lo stesso test con input diversi.
# test_add.py import pytest from add import add @pytest.mark.parametrize("a, b, expected", [ (2, 3, 5), (-1, 1, 0), (0, 0, 0), (100, 200, 300) ]) def test_add_numbers(a, b, expected): assert add(a, b) == expected
Spiegazione del codice:
- Utilizziamo il decoratore
pytest.mark.parametrize
per definire più set di input (a
,b
eexpected
). - Il test
function test_add_numbers()
verrà eseguito una volta per ciascun set di input.
Esegui nuovamente i test con il comando pytest, che eseguirà il test quattro volte, una per ciascun set di input.
Conclusione
In questo articolo, abbiamo imparato come scrivere ed eseguire test unitari efficaci in Python utilizzando PyTest per catturare bug in anticipo e garantire che il tuo codice funzioni come previsto.
PyTest rende facile scrivere e eseguire questi test e con le sue potenti funzionalità, puoi gestire esigenze di test più complesse man mano che progredisci nel tuo percorso con Python.
Source:
https://www.tecmint.com/unit-testing-python-code-with-pytest/