G. Mecca – Università della Basilicata – mecca@unibas.it
Programmazione Procedurale in Linguaggio C++
Sottoprogrammi Concetti Avanzati
Tecniche di Test e Correzione
versione 2.4
Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)
2
Sommario
m
Tecniche di Test e Correzione
m
Test di Regressione
m
Utilizzo del Debugger
ðIl Turbo DebuggerSottoprogrammi: Concetti Avanzati >> Sommario
G. Mecca - Programmazione Procedurale in Linguaggio C++ 3
Tecniche di Test e Correzione
m
Dopo la scrittura del codice
ðè necessario condurre le verifiche (test) ðed eliminare gli eventuali errori logici
m
Il metodo tipico di test
ðtest manuale e interattivom
Il metodo tipico di correzione
ðmetodo delle stampe4
Tecniche di Correzione
m
Queste tecniche
ðfunzionano per programmi dalla logica applicativa semplice
ðcon un piano dei test semplici
m
Principale svantaggio
ði test sono eseguiti interattivamente
ðil programmatore è costretto a ripeterli tutte le volte che effettua modifiche
ðprocesso noioso e aperto agli errori
Sottoprogrammi: Concetti Avanzati >> Tecniche di Test e Correzione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 5
Tecniche di Correzione
m
In casi più complessi
ðprogrammi con logica applicativa complessa ðin cui il codice viene sottoposto a frequenti
modifiche
ðè opportuno adottare tecniche alternative ðe strumenti alternativi
m
Test di Regressione
m
Debugger
6
Test di Regressione
m
Idea
ðprogrammare i test scrivendo il codice relativo
ðin modo che siano totalmente automatizzati ðe siano eseguibili rapidamente,
ripetutamente, senza intervento interattivo ð“eseguire i test deve costare quanto
schiacciare un tasto”
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 7
Test di Regressione
m
Vantaggio di questo approccio
ðè possibile effettuare più facilmentemodifiche al codice
ðscoprendo presto eventuali “regressioni”
(passi indietro), ovvero errori introdotti dalle modifiche
ðin modo da poterli eliminare concentrandosi solo sulle porzioni di codice scorrette
ði test diventano un “paracadute”
8
Test di Regressione
m
Cos’é un test
ðun pezzo di codice aggiuntivo rispetto a quello dell’applicazione
ðche utilizza uno o più sottoprogrammi dell’applicazione
ðfornendo dei dati stabiliti dal programmatore ðe facendo asserzioni sul risultato atteso ðil test è superato se l’asserzione è vera
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 9
Test di Regressione
m
Un esempio
ðsovrapposizione di rettangoli
m
Caratteristiche del problema
ðlogica applicativa complessaðvari raffinamenti nella scelta della soluzione (concepimento della formula)
ðpiano di test elaborati
10
Test di Regressione
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
TEST n. 1
rettangolo 1: (1, 2) – (7, 6) rettangolo 2: (3, 1) – (8, 5)
rettangolo 1: (-2, 3.5) – (3, 5.5) rettangolo 2: (2, 1) – (6.2, 3) sovrapposizione: 12 cm2 sovrapposizione: 0
TEST n. 2
G. Mecca - Programmazione Procedurale in Linguaggio C++ 11
Test di Regressione
TEST n. 3
rettangolo 1: (-1, 1) – (7, 6) rettangolo 2: (3, 2) – (6, 5)
rettangolo 1: (-2, 1) – (3, 5.5) rettangolo 2: (3, 1) – (7.2, 3) sovrapposizione: 9 cm2 sovrapposizione: 0
TEST n. 4
12
Test di Regressione
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
TEST n. 5
rettangolo 1: (-1, 1) – (7, 6) rettangolo 2: (4, 2) – (7, 5)
rettangolo 1: (-2, 3) – (3, 5.5) rettangolo 2: (3, 1) – (7.2, 3) sovrapposizione: 9 cm2 sovrapposizione: 0
TEST n. 6
>> rettangoli2.cpp
>> rettangoli2Test.cpp
G. Mecca - Programmazione Procedurale in Linguaggio C++ 13
La Procedura assert
void assert (string s, bool asserzione) { if (!asserzione) {
cout << "\n ****Errore: " << s << endl;
//exit(0);
} else {
cout << ".";
}
return;
}
14
Un Esempio di Test
void testAreaSovrapposizione1() {
cout << "\n**testAreaSovrapposizione1\n";
rettangolo r1 = {{1, 2}, {7, 6}};
rettangolo r2 = {{3, 1}, {8, 5}};
float area;
area = areaSovrapposizione(r1, r2);
assert("Test area n.1", area == 12);
return;
}
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 15
Un Esempio di Test
void main() {
testQuadrante1();
testMinimo1();
testMassimo1();
testLunghezzaSegmentoComune1();
testLunghezzaSegmentoComune2();
testAreaSovrapposizione1();
testAreaSovrapposizione2();
testAreaSovrapposizione3();
testAreaSovrapposizione4();
testAreaSovrapposizione5();
testAreaSovrapposizione6();
}
16
Test di Regressione
m
L’approccio
ðscrivere molti piccoli test
ðverificando tutti i sottoprogrammi ðin condizioni diverse di utilizzo
m
Test di Unità (“Unit Tests”)
ðle unità (i moduli) che compongono il codice vengono verificate una per una
ðper accertare il funzionamento corretto di ciascuno
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 17
Test di Regressione
m
Alcune annotazioni
ðil sistema richiede di scrivere molto codice aggiuntivo (il codice dei test)
ði test diventano essi stessi parte della base di codice e devono essere manutenuti
ðil sistema di per sé non garantisce
l’eliminazione degli errori (dipende da come sono scritti i test)
18
Test di Regressione
m
Attenzione
ðnon è possibile effettuare test sugli schermi ðè possibile effettuare test solo sui
sottoprogrammi “di calcolo” e quelli “per la persistenza”
ðinfatti: questi ultimi sono riutilizzabili (anche a scopo di test) i primi no
ðulteriore conferma dell’importanza della separazione
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 19
Test di Regressione
m
Test sugli schermi
ðtest “funzionali”ðtest che verificano che l’interazione con l’utente si svolga correttamente
ðe i risultati forniti siano quelli corretti ðun’altra categoria di test
m
In generale
ðsono necessari sia test di unità che test funzionali
20
Test di Regressione
m
Di conseguenza
ðattenzione a come scrivete il codice
m
Esempio: stampa del quadrante
int calcolaQuadrante(punto p);
void schermoStampaQuadrante(punto p){
int q = calcolaQuadrante(p);
cout << “Quadrante: “ << q << endl;
return;
}
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
Chiara separazione tra il modulo di calcolo e il modulo di schermo
G. Mecca - Programmazione Procedurale in Linguaggio C++ 21
Test di Regressione
m
Alternativa scorretta
void quadrante(punto p){
int q = 4;
if (p.x >= 0 && p.y >= 0) q = 1;
else if (p.x < 0 && p.y >= 0) q = 2;
else if (p.x < 0 && p.y < 0) q = 3;
cout << “Quadrante :” << q << endl;
return;
}
Questo modulo effettua contemporaneamente calcolo ed interazione;
sul codice che calcola il quadrante non è possibile effettuare test
22
Test di Regressione
m
Cosa fare in caso di scoperta di un baco
ðerrore logico nel codice non catturato da untest
ðprima operazione: scrivere un test che cattura il baco (in modo che fallisca)
ðseconda operazione: correggere il codice, in modo che il test abbia successo
Sottoprogrammi: Concetti Avanzati >> Test di Regressione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 23
Test di Regressione
m
Come correggere gli errori ?
ðil sistema aiuta moltissimo ad identificarli ðil sottoprogramma scorretto viene
immediatamente identificato
m
Primo approccio
ðispezione del codicem
Secondo approccio
ðutilizzo del debugger24
Utilizzo del Debugger
m
Debugger (“Correttore”)
ðstrumento che consente di ispezionare la pila di attivazione durante il funzionamento di un programma
ðverificando i valori delle variabili ðverificando i valori dei parametri ðin modo da seguire passo passo
l’esecuzione del codice per trovare dove si verificano gli errori
Sottoprogrammi: Concetti Avanzati >> Utilizzo del Debugger
G. Mecca - Programmazione Procedurale in Linguaggio C++ 25
Utilizzo del Debugger
m
Funzionalità principali
ðconsente di eseguire il programma
decidendo punti di interruzione (“breakpoint”) ðad ogni breakpoint l’esecuzione si interrompe ðè possibile ispezionare la pila di attivazione
in corrispondenza dei punti di interruzione ðè possibile analizzare il contenuto dei record
di attivazione per verificare i valori in memoria
26
Utilizzo del Debugger
m
Un esempio per il C++
ðil Turbo Debugger 5.5 della Borland
ðpensato per funzionare con il compilatore Borland BCC 5.5
ðdistribuito gratuitamente come il compilatore sul sito www.borland.com
m
Un esempio per il FORTRAN
ðil compilatore SALFORD ha un debugger apposito a corredo (Programmi >> Salford)
Sottoprogrammi: Concetti Avanzati >> Utilizzo del Debugger
G. Mecca - Programmazione Procedurale in Linguaggio C++ 27
Utilizzo del Turbo Debugger
m
Per usare il Turbo Debugger
ðè necessario compilare il codice utilizzando l’opzione di debugging –v
ðesempio: bcc32 –v prova.cpp m
Per lanciare il Turbo Debugger
ðtd32 prova.exe
Turbo Debugger >>
28
Utilizzo del Turbo Debugger
Sottoprogrammi: Concetti Avanzati >> Utilizzo del Debugger
G. Mecca - Programmazione Procedurale in Linguaggio C++ 29
Utilizzo del Turbo Debugger
m
Punti di Interruzione (“Breakpoint”)
ðsi attivano/disattivano selezionando la linea di codice sorgente corrispondente e
premendo F2
ðattenzione: solo se la linea è preceduta da un punto (.)
ðil codice dell’applicazione è diviso in “pezzi”
per il debugging
ðper vedere l’elenco dei pezzi CTRL-F
30
Utilizzo del Turbo Debugger
m
In corrispondenza dei breakpoint
ðvari comandi disponibilim
In particolare
ðè possibile esplorare la pila
ðè possibile valutare condizioni (es: condizioni di controllo degli if o dei while)
ðè possibile effettuare il log su file o in una finestra particolare degli eventi
ðè possibile continuare
Sottoprogrammi: Concetti Avanzati >> Utilizzo del Debugger
G. Mecca - Programmazione Procedurale in Linguaggio C++ 31
Utilizzo del Turbo Debugger
m Continuare fino al breakpoint successivo
ð“continue”
m Procedere passo passo
ðesegue solo l’istruzione successiva
ð“trace into” (o “step into”): se l’istruzione contiene la chiamata di un sottoprog., dettagliare l’esecuzione ð“step over”: se l’istruzione contiene la chiamata di un
sottoprog., ignorare i dettagli dell’esecuzione
32
Riassumendo
m
Tecniche di Test e Correzione
ðIl Metodo delle Stampem
Test di Regressione
m
Utilizzo del Debugger
ðIl Turbo DebuggerSottoprogrammi: Concetti Avanzati >> Sommario
G. Mecca - Programmazione Procedurale in Linguaggio C++ 33
Termini della Licenza
m This work is licensed under the Creative Commons Attribution- ShareAlike License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
m Questo lavoro viene concesso in uso secondo i termini della licenza “Attribution-ShareAlike” di Creative Commons. Per ottenere una copia della licenza, è possibile visitare
http://creativecommons.org/licenses/by-sa/1.0/ oppure inviare una lettera all’indirizzo Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.