Che cosa sono i test unitari?

Il test unitario è il processo in cui si esegue il test della più piccola unità funzionale di codice. I test del software contribuiscono a garantire la qualità del codice e sono parte integrante dello sviluppo del software. È una best practice di sviluppo scrivere il software sotto forma di piccole unità funzionali, quindi scrivere un test unitario per ciascuna unità di codice. I test unitari possono essere scritti inizialmente sotto forma di codice. Dopodiché, è possibile eseguire automaticamente il codice di test ogni volta che vengono apportate modifiche al codice del software. In questo modo, se un test fallisce, è possibile isolare rapidamente l'area del codice che presenta il bug o l'errore. Il test unitario applica i paradigmi di pensiero modulare e migliora la copertura e la qualità dei test. I test unitari automatizzati aiutano a garantire che tu e i tuoi sviluppatori abbiate più tempo per concentrarvi sulla scrittura del codice.

Cos'è un test unitario?

Un test unitario è un blocco di codice che verifica l'accuratezza di un blocco di codice applicativo più piccolo e isolato, in genere una funzione o un metodo. Il test unitario è progettato per verificare che il blocco di codice funzioni come previsto, secondo la logica teorica seguita dallo sviluppatore. Il test unitario è in grado di interagire con il blocco di codice solo tramite gli input e i relativi output di risposta (vero o falso) acquisiti. 

Un singolo blocco di codice può anche avere una serie di test unitari, noti come casi di test. Una gamma completa di casi di test copre l'intero comportamento previsto del blocco di codice, ma non sempre è necessario definire l'intero set di casi di test.

Quando un blocco di codice richiede l'esecuzione di altre parti del sistema, non è possibile utilizzare un test unitario con quei dati esterni. Il test unitario deve essere eseguito in modo isolato. Per la funzionalità del codice potrebbero essere necessari altri dati di sistema, come database, oggetti o comunicazioni di rete. In tal caso, si dovrebbero invece utilizzare gli stub di dati. È più semplice scrivere test unitari per blocchi di codice piccoli e logicamente semplici.

Strategie di test unitari

Per creare test unitari, è possibile seguire alcune tecniche di base per garantire la copertura di tutti i casi di test.

Controlli logici

Il sistema esegue i calcoli corretti e segue il percorso giusto attraverso il codice, dato un input corretto e previsto? Tutti i percorsi del codice sono coperti dagli input forniti?

Controlli dei confini

Come risponde il sistema agli input forniti? Come risponde agli input tipici, ai casi limite o agli input non validi?

Supponiamo che ci si aspetti un input intero compreso tra 3 e 7. Come risponde il sistema quando si utilizza un 5 (input tipico), un 3 (caso limite) o un 9 (input non valido)?

Gestione degli errori

In caso di errori negli input, come risponde il sistema? All'utente viene richiesto un altro input? Il software si blocca?

Controlli orientati agli oggetti

Se lo stato di un oggetto persistente viene modificato eseguendo il codice, l'oggetto viene aggiornato correttamente?

Esempio di test unitari

Ecco un esempio di un metodo molto semplice in Python e alcuni casi di test con il codice di test unitario corrispondente.

Metodo Python

def add_two_numbers(x, y):

    return x + y

Test unitari corrispondenti

def test_add_positives():

    result = add_two_numbers(5, 40)

    assert result == 45

def test_add_negatives():

    result = add_two_numbers(-4, -50)

    assert result == -54

def test_add_mixed():

    result = add_two_numbers(5, -5)

    assert result == 0  

Quali sono i vantaggi dei test unitari?

I test unitari offrono numerosi vantaggi ai progetti di sviluppo del software.

Rilevamento efficiente dei bug

Se sono presenti errori di input, output o di logica all'interno di un blocco di codice, i test unitari contribuiscono a rilevarli prima che i bug raggiungano la produzione. Quando il codice viene modificato, viene eseguito lo stesso set di test unitari, insieme ad altri test come i test di integrazione, aspettandosi i medesimi risultati. Se i test falliscono (oppure non funzionano), significa che sono presenti bug basati sulla regressione. 

Inoltre, i test unitari contribuiscono a individuare più velocemente i bug all'interno del codice. Gli sviluppatori non devono dedicare molto tempo alle attività di debug. Possono individuare rapidamente l'esatta porzione del codice che presenta un errore.

Documentazione

È importante documentare il codice per sapere esattamente cosa dovrebbe fare. Detto questo, i test unitari fungono anche da forma di documentazione.

Altri sviluppatori leggono i test per vedere quali comportamenti dovrebbe mostrare il codice durante l'esecuzione. Usano le informazioni per modificare o rifattorizzare il codice. La rifattorizzazione del codice lo rende più performante e ben composto. Dopo una serie di modifiche, è possibile eseguire nuovamente il test unitario per verificare che il codice funzioni come previsto.

In che modo gli sviluppatori utilizzano i test unitari?

Gli sviluppatori utilizzano i test unitari in varie fasi del ciclo di vita dello sviluppo del software. 

Sviluppo basato sui test

Lo sviluppo basato sui test (TDD) si riferisce a quando gli sviluppatori creano dei test per verificare i requisiti funzionali di un software prima di creare il codice nella sua interezza. Se si scrivono i test anticipatamente, una volta terminata la scrittura del codice e condotti i test unitari è possibile verificare immediatamente se il codice soddisfa i requisiti.

Dopo il completamento di un blocco di codice

Una volta che un blocco di codice è considerato completo, è necessario sviluppare test unitari, se non si è già provveduto tramite TDD. Dopodiché, è possibile eseguire immediatamente test unitari per verificare i risultati. I test unitari vengono eseguiti anche come parte della suite completa di altri test software durante i test di sistema. In genere sono la prima serie di test che vengono eseguiti durante il test completo del software di sistema.

Efficienza del DevOps

Una delle attività principali nell'applicazione del DevOps alle pratiche di sviluppo software è l'integrazione continua e la distribuzione continua (CI/CD). Qualsiasi modifica al codice viene automaticamente integrata nella base di codice più ampia, eseguita tramite test automatici e quindi implementata se i test hanno esito positivo.

I test unitari fanno parte della suite di test accanto ai test di integrazione. Vengono eseguiti automaticamente nella pipeline CI/CD per garantire la qualità del codice man mano che viene aggiornato e modificato nel tempo.

Quando sono meno vantaggiosi i test unitari?

Non sempre è necessario condurre test unitari per ogni singolo caso di test in ogni singolo blocco di codice di ciascun progetto. Ecco alcuni esempi di quando i test unitari potrebbero essere potenzialmente omessi. 

Quando il tempo è limitato

Anche utilizzando framework generativi di test unitari, la scrittura di nuovi test unitari richiede agli sviluppatori una notevole quantità di tempo. Sebbene i test unitari basati su input e output possano essere facili da generare, i controlli basati sulla logica sono più difficili.

Una volta che iniziano a scrivere i test, gli sviluppatori notano anche le opportunità di rifattorizzazione nel blocco di codice e si distraggono dal completare i test. Ciò può portare a tempistiche di sviluppo prolungate e problemi di budget.

Applicazioni UI/UX

Quando il sistema principale si occupa dell'aspetto estetico anziché della logica, potrebbero non esserci molti test unitari da eseguire. In questi casi, altri tipi di test, come i test manuali, rappresentano una strategia migliore rispetto ai test unitari.

Basi di codice legacy

Scrivere test per integrare il codice legacy esistente può rivelarsi quasi impossibile, a seconda dello stile del codice scritto. Poiché i test unitari richiedono dati fittizi, anche scrivere test di questo tipo per sistemi altamente interconnessi con numerose analisi dei dati può portare via moltissimo tempo.

Requisiti in rapida evoluzione

A seconda del progetto, in qualsiasi fase di sviluppo il software può crescere, cambiare direzione o spogliarsi di intere parti. Se è probabile che i requisiti cambino spesso, non ha molto senso scrivere test unitari ogni volta che viene sviluppato un blocco di codice.

Quali sono le best practice per i test unitari?

Ecco alcune best practice sui test unitari per ottenere il massimo dal tuo processo.

Utilizzo di un framework per i test unitari

Scrivere test unitari espliciti e completamente personalizzati per ogni singolo blocco di codice è una perdita di tempo. Esistono framework di test automatizzati per tutti i linguaggi di programmazione più diffusi.

Ad esempio, Python offre due diversi framework per i test unitari: pytest e unittest. I framework di test sono ampiamente utilizzati nei progetti di sviluppo software di ogni dimensione.

Automatizzazione dei test unitari

I test unitari dovrebbero essere condotti quando si verificano eventi diversi all'interno del ciclo di sviluppo del software. Ad esempio, è possibile applicarli prima di inviare le modifiche a un ramo utilizzando un software di controllo della versione o prima di implementare un aggiornamento software.

I test unitari possono essere eseguiti anche su un progetto completo secondo una pianificazione puntuale. I test unitari automatizzati garantiscono l'esecuzione dei test in tutti gli eventi e i casi appropriati durante ogni fase del ciclo di vita dello sviluppo.

Unica asserzione

Ogni test unitario dovrebbe produrre un solo risultato: vero o falso. All'interno di ogni test si dovrebbe includere una sola dichiarazione di asserzione. Se una delle asserzioni all'interno di un blocco fallisce, potrebbe causare incertezza sulla vera causa del problema.

Implementazione dei test unitari

Il test unitario è una parte importante della creazione di software, ma molti progetti lo trascurano. Quando i progetti iniziano come prototipi o come piccole iniziative basate sulla community, o più semplicemente vengono scritti rapidamente, i test unitari possono essere tralasciati per via del tempo limitato.

Tuttavia, quando si creano progetti integrando i test unitari come pratica standard sin dall'inizio, il processo diventa molto più semplice da seguire e ripetere.

Qual è la differenza tra i test unitari e altri tipi di test?

Oltre ai test unitari, esistono molti altri tipi di metodi di test del software. Ciascuno di essi svolge un ruolo specifico nel ciclo di vita dello sviluppo del software:

  • I test di integrazione verificano che le diverse parti del sistema software progettate per interagire lo facciano correttamente.
  • I test funzionali verificano se il sistema software soddisfa i requisiti del software individuati prima dello sviluppo.
  • I test delle prestazioni verificano se il software funziona secondo i requisiti di prestazione previsti, come velocità e dimensioni della memoria.
  • I test di accettazione comprendono prove manuali condotte dagli stakeholder o dai gruppi di utenti per verificare se il software funziona secondo le aspettative.
  • I test di sicurezza verificano il software rispetto a vulnerabilità e minacce note. Ciò include l'analisi della superficie di attacco delle minacce, compresi i punti di accesso di terze parti al software.

Questi metodi di test di solito richiedono strumenti specializzati e processi indipendenti per controllare il software. Molti di questi vengono eseguiti anche dopo lo sviluppo delle funzionalità di base dell'applicazione. 

Al contrario, i test unitari vengono eseguiti ogni volta che il codice viene compilato. Possono essere scritti non appena viene scritto un blocco di codice e la loro esecuzione non richiede strumenti speciali. Il test unitario è considerato uno dei tipi più elementari di test del software.

In che modo AWS può supportare i requisiti di test unitari?

Amazon Web Services (AWS) offre agli sviluppatori una vasta gamma di vantaggi. Permette di sviluppare ed eseguire codice e testare software, ad esempio tramite test unitari e test di integrazione. Inoltre, offre la possibilità di eseguire pipeline DevOps e di perseguire molte opportunità di sviluppo.

Gli strumenti per gli sviluppatori di AWS offrono ambienti di sviluppo integrato (IDE), plug-in e SDK che supportano vari linguaggi di programmazione e coprono una vasta gamma di casi d'uso. Tra gli altri vantaggi, questi strumenti rendono più efficienti i test unitari.

AWS Fargate è un motore di calcolo serverless con pagamento in base al consumo che consente di concentrarsi sulla creazione di applicazioni senza occuparsi della gestione dei server. Per semplificare lo sviluppo delle applicazioni, è possibile eseguire facilmente un software di test unitario automatizzato su Fargate. 

Nel Marketplace AWS sono inoltre disponibili software di test unitari di terze parti. È possibile implementare il software rapidamente e con i controlli necessari. I venditori presenti sul Marketplace AWS offrono opzioni di prezzo flessibili, permettendo di pagare solo ciò che è necessario nel momento in cui serve.

Inizia a svolgere i test unitari su AWS creando un account oggi stesso.

Fasi successive su AWS

Scopri ulteriori risorse correlate al prodotto
Consulta i servizi di strumenti per sviluppatori 
Registrati per creare un account gratuito

Ottieni accesso istantaneo al Piano gratuito di AWS.

Registrati 
Inizia a lavorare nella console

Inizia subito a creare nella Console di gestione AWS.

Accedi