Processo e tecniche di testing e debugging del software

Processo e tecniche di testing e debugging del software

Il ciclo di vita del software

In ingegneria del software, con il termine ciclo di vita del software ci si riferisce alle fasi attraversate da un progetto software durante la sua evoluzione, dall’idea iniziale alla manutenzione. Il risultato finale è il prodotto software stesso, accompagnato da tutta la documentazione ad esso associata.

Le fasi, che rispecchiano quanto definito dal modello a cascata, sono:

  1. Raccolta dei requisiti
  2. Analisi
  3. Progettazione
  4. Implementazione (o sviluppo)
  5. Test
  6. Installazione in produzione
  7. Manutenzione (ordinaria ed evolutiva)

La fase di implementazione (Coding)

La scrittura del codice sorgente può essere svolta con molti strumenti, il più semplice dei quali è l’editor di file ASCII di base (notepad, gedit, ecc.). Per la complessità che i moderni linguaggi ad oggetti richiedono però tale approccio è troppo poco produttivo. Dovendo infatti garantire il rispetto di tempi stretti, è necessario disporre di tutte le funzioni di facilitazione integrate entro un unico strumento per la scrittura del codice sorgente.

Un Integrated Development Environment (IDE), è un software che aiuta i programmatori nello sviluppo del codice. Normalmente consiste in un editor di codice sorgente, un compilatore e/o un interprete, un tool di building automatico, e (solitamente) un debugger. Ormai sempre più spesso è integrato con sistemi di controllo di versione (SVN o GitHub, ad esempio), con sistemi di gestione delle dipendenze da librerie esterne (Maven) e con uno o più tool per semplificare la costruzione di una GUI.

Alcuni IDE, rivolti allo sviluppo di software orientato agli oggetti, comprendono anche un navigatore di classi, un analizzatore di oggetti e un diagramma della gerarchia delle classi. Sebbene siano in uso alcuni IDE multi-linguaggio, come Eclipse, NetBeans, IntelliJ Idea e Visual Studio, generalmente gli IDE sono rivolti ad uno specifico linguaggio di programmazione.

La scrittura del codice sorgente, per quanto spesso poco considerata, rimane comunque la fase fondamentale di ogni progetto informatico. L’analisi e la progettazione possono essere state svolte al meglio, ma, se il codice viene scritto male, l’applicazione risultante avrà problemi e funzionerà male. Facendo un’analogia nell’ambito dell’ingegneria civile, è chiaro che anche il progetto più bello, se i pilastri non sono fabbricati bene, se i mattoni non sono posati con accuratezza o se i materiali impiegati sono di scarso pregio, darà origine ad un edificio di pessima qualità.

Anche per questo, metodologie di programmazione più moderne tendono a fare diventare la fase di scrittura del codice quella principale in tutto il progetto informatico.
Durante la stesura del codice ha luogo anche il primo debugging, ossia la rimozione degli errori di sintassi e degli errori più evidenti, come la mancata inizializzazione di variabili, che possono compromettere la compilazione o il funzionamento del programma. Gli IDE più moderni hanno ottimi sistemi di live debug. Tendono ad evidenziare in tempo reale, oltre al codice che inevitabilmente porterà ad errori di compilazione, anche frammenti di codice inutili, blocchi ripetuti, inizializzazioni di variabili non necessarie, ecc.

Processo e tecniche di testing e debugging del software

La fase di Test

Una volta che il programma è stato completato o comunque può iniziare a funzionare, occorre verificare che il suo funzionamento sia conforme a tutte le specifiche che erano state stabilite nella fase di analisi. Questo è lo scopo fondamentale della fase di test.

Gli errori che portano al non rispetto delle specifiche sono di solito molto più insidiosi da scoprire rispetto a quelli che vengono trovati durante il debugging. Non sono errori di sintassi, ma errori logici e concettuali, come, per esempio, lo scrivere il segno ‘+’ invece del segno ‘-‘ entro un algoritmo che richieda la sottrazione e non la somma.
La fase di test prevede quindi di verificare il comportamento effettivo del programma rispetto a quello previsto e di segnalare le differenze di comportamento ai programmatori che dovranno procedere alla ricerca e alla eliminazione delle cause di tali differenze.

I modelli di sviluppo software più moderni pongono l’accento sulla fase di test, anteponendola in alcuni casi alla fase di sviluppo (ad esempio il Test Driven Development, TDD) e prevedendo l’esistenza di suite di test eseguite automaticamente durante la build ed il packaging del progetto, allo scopo di ridurre il più possibile il rischio di regressione.

Tecniche di testing

Le tecniche di test del software consentono dunque di progettare casi di test migliori. Dal momento che test esaustivi non sono possibili; Le tecniche di test manuali aiutano a ridurre il numero di casi di test da eseguire aumentando la copertura dei test. Aiutano a identificare condizioni di test che altrimenti sarebbero difficili da riconoscere.

White Box

Si possono distinguere due macro aree che definiscono le metodologie di testing di un prodotto software. WHITE Box e BLACK Box. In questo articolo, ci si soffermerà solo sul BLACK Box ma è giusto accennare alle tecniche WHITE Box. Questo tipo di testing è molto efficace e performante in quanto, il tester ha una conoscenza approfondita delle strutture interne e del codice del prodotto software. Viene effettuato durante lo sviluppo stesso del software, localizzato a singoli moduli prima di testare tutto il sistema.

Questo è adoperato anche come test di sicurezza per valutare se l’attuazione del codice segue la progettazione di funzionalità di sicurezza, in modo da scoprire vulnerabilità sfruttabili per attacchi esterni. Gli strumenti a supporto di questa tipologia di test sono di source code analysis, program understanding, code coverage e profiling.

Black Box

Parlando ora di BLACK Box, è la metodologia usata specificatamente prima del rilascio finale del software. Il tester non conosce come è fatto il sistema, non sa come i moduli interagiscono fra di loro, ma conosce solo le specifiche e i requisiti. I problemi di un processo di testing sono la selezione dei Test Case, la valutazione dei risultati e la terminazione. Si introduce la figura dell’oracolo, umano o automatico, che ha la caratteristica di conoscere il comportamento atteso per ogni caso di test. Viene da sè l’importanza di questa figura nel testing black box poichè, grazie alla conoscenza dei risultati attesi, funge da metro di comparazione con i comportamenti riscontrati durante il test.

Il testing black box comprende varie tecniche atte a massimizzare l’efficacia, usando il minor numero di Test Case per trovare il maggior numero di bug possibili. Descriviamo dunque alcune delle tecniche maggiormente utilizzate.

Equivalence Class Partitioning

Innanzitutto, si divide lo spazio degli ingressi in insiemi con tutti i valori di input assunti equivalenti. Si può quindi testare un solo valore rappresentativo di ogni partizione e
coprire tutto lo spazio degli ingressi e per ciascuna condizione di input si associano due classi di equivalenza, una valida e una invalida. Per poter definire le classi di equivalenza bisogna sottostare a determinate “regole” in base al tipo di variabile d’ingresso. Se l’input si basa su un intervallo di valori, bisognerà definire tre classi, una per valori interni all’intervallo, una per valori inferiori al minimo accettabile e una per valori superiori al massimo accettabile. Si possono considerare due ulteriori classi per i valori limite dell’intervallo (estremo superiore ed inferiore) per quelle applicazioni in cui questi input potrebbero generare problemi. Se l’input è valido solo per un valore specifico, definiremo tre classi, una valida per quel determinato valore, una non valida per valori inferiori ed una per valori superiori. Se l’input fa parte di un insieme discreto, definiremo una classe per ogni elemento dell’insieme ed una per un elemento non appartenente. L’imperativo da seguire è che ogni classe deve essere coperta da almeno un Test Case. Nello specifico si deve generarne uno per ogni classe non valida e, quelli per le classi valide, dovrebbero comprendere il maggior numero di classi ancora scoperte.

Boundary Value Analysis

Il Boundary Value Analysis consiste nell’ampliare la tecnica delle classi di equivalenza per quelle applicazioni in cui valori limite di un intervallo possono avere comportamenti particolari. Un boundary value potrebbe essere il valore 0 nel caso di una divisione tra numeri interi.

Cause-Effect Graphing

Il Cause-Effect Graphing (abbreviato CEG) è una tecnica dinamica di scrittura di test case. Si associano alle “cause” le condizioni in ingresso ed agli “effetti” i risultati di tali condizioni. Grazie a questa tecnica, determiniamo, a partire dai requisiti, il minor numero di casi di test possibili per un test a copertura massima in modo da ridurre il tempo di esecuzione e i costi. La riduzione del numero totale di test case non dovrà influire sulla qualità desiderata per l’applicazione e ciò è un obiettivo da raggiungere. Ci sono anche aspetti negativi da tener conto, infatti utilizzare questa tecnica significa spendere del tempo per modellare tutte le specifiche richieste nel grafico prima di poter scrivere i test case. Grazie a CEG si andrà a tradurre i requisiti in termini di relazioni logiche tra condizioni di input ed output e, parlando di logica, è lecito utilizzare operatori booleani come AND, OR e NOT.

Comparision Testing

Comparision Testing è un tipo di test che permette di valutare la competitività e l’utilità del prodotto software sul mercato. I tester confrontano i punti di forza e di debolezza del proprio prodotto con altri software già presenti sul mercato per capire se sarà utile e appetibile per gli utenti finali, quindi consente di sapere se il prodotto è commerciabile oppure no e se ha una buona possibilità di essere redditizio. I vantaggi sono quindi la determinazione dei punti deboli del proprio software e la conoscenza della struttura dei prodotti concorrenti che si potrebbe usare per miglioramenti futuri al proprio prodotto. Si tratta di un vero e proprio strumento di Benchmark. Purtroppo conducendo questo tipo di test, i concorrenti e gli utenti finali sapranno di eventuali carenze e debolezze del prodotto ed è complesso introdurre modifiche o nuove funzionalità per cui questo test ha senso solo dopo aver condotto tutti gli altri test, come white box, black box e testing di integrazione.

Pubblicato da Vito Lavecchia

Lavecchia Vito Ingegnere Informatico (Politecnico di Bari) Email: [email protected] Sito Web: https://vitolavecchia.altervista.org

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *