Cosa si intende per test unitario? - MATLAB & Simulink

Test unitari

Cosa si intende per test unitario?

I test unitari, o unit testing, sono una tecnica di prova dei software per verificare la funzionalità dei singoli componenti, detti unità, di un programma in isolamento dal resto dell’applicazione.

Per “unità” in genere ci si riferisce alla parte testabile più piccola di un programma, come una funzione, un metodo, una classe o uno script. Suddividendo gli script o gli algoritmi complessi in queste unità più piccole, è possibile sviluppare dei test precisi e mirati per validare la funzionalità di ciascun componente.

Illustrazione dei pezzi di un puzzle come analogia dei componenti di un sistema. I test unitari si concentrano su un singolo pezzo (o componente) e sui pezzi adiacenti piuttosto che sull’intero sistema.

I pezzi del puzzle rappresentano i singoli componenti di un’applicazione. Con i test unitari ci si accerta che ogni componente funzioni correttamente in isolamento.

Perché i test unitari sono importanti?

Eseguendo i test unitari sulle singole unità in fase anticipata, è possibile individuare e correggere gli errori, ottenendo un codice più affidabile e progetti di debugging meno complicati e dispendiosi in termini di tempo. In più, supportano lo sviluppo di software modulari e manutenibili che, a loro volta, migliorano la qualità del codice.

Vantaggi e sfide dei test unitari

I test unitari offrono diversi vantaggi:

  • I test unitari in genere sono più facili da scrivere e più rapidi da eseguire rispetto ai test a livello di sistema o più globali.
  • Probabilmente è più semplice identificare e isolare i bug nelle prime fasi.
  • Potrebbero aiutare a identificare problemi in altre parti del software, mantenendo il numero di interazioni tra i sottosistemi al minimo.
  • I test possono essere svolti fin dalle prime fasi di sviluppo, senza dover attendere il completamento dell’intera applicazione. 

Tuttavia, con i test delle singole unità isolate si corre il rischio di non rilevare tutti i problemi.

Quando eseguire i test unitari

Per garantire la qualità del codice e riconoscere le conseguenze delle modifiche apportate al codice, i test unitari dovrebbero essere svolti lungo l’intero processo di sviluppo:

  • In fase di sviluppo: scrivi i test unitari man mano che vengono sviluppate nuove funzionalità. Questo approccio garantisce che ogni componente funzionerà come previsto fin dall’inizio.
  • Al momento del refactoring: usa i test unitari per assicurati che il refactoring non alteri il comportamento previsto del codice.
  • Dopo la correzione dei bug: implementa i test unitari per i bug che sono stati risolti per impedire che si ripresentino in futuro e assicurarti che le correzioni non abbiano influito negativamente su altre funzionalità del software.
  • Prima e durante l’integrazione: conduci dei test unitari prima di unire le modifiche al codice principale e di incorporarle nella tua pipeline di integrazione continua (CI). Ciò impedisce l’introduzione di errori nel nuovo codice e aiuta a mantenere il codebase stabile.

La piramide di test per i software

L’esecuzione di test unitari fin dalle prime fasi e per tutto il processo di sviluppo di un software aiuta a ottenere un codice di maggiore qualità. Tuttavia, i test unitari non sono che una parte di una strategia globale. La piramide di test per i software illustra i vari livelli di test (test unitari, di integrazione e di sistema) evidenziandone la granularità e la frequenza. Questa piramide offre un approccio strutturato per gestire e dare priorità alle operazioni di test, sottolineando l’equilibrio necessario a ottenere livelli di qualità ottimali del software.

Ecco quali sono le caratteristiche di questi tipi di test:

  • I test unitari, alla base della piramide, sono quelli più granulari e utilizzati con maggiore frequenza. I test unitari in genere sono piccoli e, pertanto, possono essere scritti ed eseguiti più rapidamente e a costi più contenuti. Possono essere implementati fin dalle prime fasi del processo di sviluppo, fornendo un feedback immediato sulla funzionalità di ogni singolo componente.
  • I test di integrazione, collocati a metà della piramide, servono a verificare le interazioni tra i vari componenti o sistemi. I test di integrazione sono leggermente più complessi e lunghi dei test unitari, ma sono fondamentali per garantire il corretto funzionamento dei componenti integrati.
  • I test di sistema, in cima alla piramide, valutano l’intera applicazione. I test di sistema sono più completi e richiedono molte risorse. In genere vengono eseguiti nelle fasi avanzate del ciclo di sviluppo per accertarsi che il sistema completo soddisfi i requisiti specificati.

La piramide evidenzia l’importanza di svolgere più test di basso livello, come i test unitari, e meno test di alto livello. Un approccio equilibrato comprenderebbe circa il 70% di test unitari, il 20% di test di integrazione e il 10% di test di sistema prima del completamento del progetto. Con questa strategia ci si assicura una base solida di codice affidabile, riducendo la probabilità che si verifichino dei problemi nel momento in cui vengono svolti i test di livello più alto.

I test unitari costituiscono la base della piramide, mentre i test di integrazione si trovano a metà e quelli di sistema in cima. Procedendo dal basso verso l’alto, i test diventano sempre più lenti e passano dai componenti più isolati a quelli più integrati.

Piramide di test per software, costituita da tre tipi di test che offrono un approccio strutturato per gestire e dare priorità alle operazioni di test.

Altre tipologie di test per i software

Oltre alla granularità e alla frequenza dei test rappresentati nella piramide di test per software, esistono svariati altri tipi di metodi di test, ciascuno con obiettivi specifici sulla base degli esisti previsti. Una distinzione chiave è quella tra test funzionali e non funzionali:

  • I test funzionali servono a verificare la corretta funzionalità e il corretto comportamento del software. Come esempi possiamo citare lo smoke testing, che verifica la funzionalità di base, e i test di regressione, che garantiscono che le modifiche apportate al codice non influiranno negativamente sulle funzionalità esistenti.
  • I test non funzionali valutano altri aspetti critici del software, come l’usabilità, la sicurezza e la stabilità. I test delle prestazioni, il tipo più comune di test non funzionale, valutano il funzionamento del software in condizioni specifiche, come il carico e la sollecitazione.

L’esecuzione sia di test funzionali che di quelli non funzionali garantisce che il software funzionerà correttamente e sarà in grado di soddisfare gli standard qualitativi.

Test unitari con MATLAB

L’attività di testing del codice fa parte integrante dello sviluppo di software di qualità. MATLAB® offre un framework robusto e integrato per eseguire test unitari che consente di scrivere i test unitari e di monitorare le regressioni nella funzionalità del codice. Il framework supporta la scrittura di test tramite classi, il che consente di strutturare i test in modo logico. In più, è possibile eseguire i test e analizzarne i risultati.

Test unitari basati su classi

Con questo approccio, i test vengono definiti come metodi all’interno di una classe. MATLAB è in grado di generare un modello generico e MATLAB Test™ un test specifico per il tuo codice. Tale approccio consente di testare script e funzioni nell’ambito dei propri metodi di test, combinando il vantaggio della programmazione orientata agli oggetti con la flessibilità di testare varie tipologie di codice. Questo esempio dimostra come si scrivono i test unitari basati su classi.

Esecuzione dei test

Dopo aver salvato il file di test, è possibile eseguire il test dalla barra degli strumenti di MATLAB. È anche possibile utilizzare la funzione runtests o l’app Test Browser di MATLAB per eseguire i test, visualizzare i risultati e correggere gli errori in modo interattivo.

Screenshot della sezione RUN della barra degli strumenti dell’editor di MATLAB che mostra le icone relative alle funzioni Run Tests, Run Current Test, Step e Stop.

Opzione Run Tests nella barra degli strumenti dell’editor di MATLAB (cfr. documentazione).

Analisi dei risultati dei test

MATLAB fornisce dei riepiloghi, dei report dettagliati e la coverage del codice per analizzare il codice sorgente.

Per funzionalità più avanzate, MATLAB Test offre strumenti aggiuntivi per ottimizzare la procedura di test, come la generazione automatizzata di test, la gestione ottimizzata dei test, l’integrazione con i sistemi CI/CD, la coverage del codice avanzata e una dashboard relativa alla qualità. Scopri di più sull’analisi dei risultati dei test.

Esempio di test unitario in MATLAB

Questo esempio dimostra come eseguire un test unitario su una semplice funzione fibonacci. Questa funzione calcola la sequenza di Fibonacci fino a un numero specificato (n). Per validarne la correttezza, forniamo degli input campione e il test unitario verifica se l’output calcolato corrisponde a quello previsto sulla base dell’input dato. Se l’output corrisponde, il test è superato. Se non corrisponde, non è superato.

function x = fibonacci (n) 
% Generate the first n Fibonacci numbers
n=6;
x = ones (1,n);
for ii = 3:n;
      x(ii) = x(ii - 1) + x(ii - 2);
end

end
% This is an autogenerated sample test for file fibonacci.m
classdef test fibonacci < matlab.unittest.TestCase

    methods (Test)

        function test_fibonacci (testCase)
            % Specify the input (s) of
            % fibonacci
            n = 6;

            % Specify the expected output(s) of
            % fibonacci
            expected_x = [1, 1, 2, 3, 5, 8];

            % Exercise the function fibonacci
            actual_x = fibonacci(n);

            testCase.verifyEqual(actual_x,expected_x);

        end
    end
end
Screenshot di MATLAB Test Browser, in cui è mostrato un test unitario riuscito della funzione fibonacci, con una spunta verde che indica che il test è stato superato.

Esecuzione di test unitari in MATLAB. MATLAB Test Browser esegue un test unitario sulla funzione fibonacci confrontando l’output calcolato con quello previsto in base agli input scelti. L’app MATLAB Test Browser (destra) indica che il test unitario è stato superato.


Esempi e consigli pratici


Riferimenti software


Vedere anche: MATLAB Test, software testing