Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del...

58
Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione [email protected]

Transcript of Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del...

Page 1: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Testing del Software

Michelangelo DiligentiIngegneria Informatica e

dell'Informazione

[email protected]

Page 2: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging● OK, avete trovato un bug, ed adesso?

Se i test sono ben congeniati, spesso accade attraverso un test

● Talvolta la sorgente del bug è evidente● Talvolta è necessario debugging del codice

Analisi dettagliata del funzionamento del codice

● Trovare la sorgente degli errori in generale (in C++) in particolare, può essere difficile

Page 3: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging● I bug sono di vario tipo

INCRT: il codice non genera uscita desiderata per alcuni input

Analisi del flusso del codice con print di debug Analisi del flusso del codice con debugger

MEMFLT: il codice genera un fault di memoria Necessario trovare l'errore con debugger Utile usare metodi di analisi degli accessi alla memoria

NONDET: il codice non ha uscita deterministica Spesso causati da utiizzo di memoria non inizializzata

(simili al tipo 2) Utile usare metodi di analisi degli accessi alla memoria

Page 4: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e print dello stato● Il primo e sempre valido metodo per il debugging di

bug INCRT Spesso metodo semplice è il più efficace Consiglio di usare il preprocessore, esempio:

#if DEBUG > 1

cerr << “Variabile pippo:” << pippo;

#endif

● Settare la variabile con opzione -DDEBUG NUM Spesso lo si fa in Makefiles con la variabile CFLAGS

Page 5: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging con gdb● GDB: GNU debugger, debugger open-source per

sistemi UNIX● Metodo più evoluto per il debugging di bug INCRT

ATTENZIONE: compilare con l'opzione -g del g++ perché il debugging sia leggibile

● Permette di eseguire un programma passo-passo Mentre si monitora lo stato di qualsiasi variabile

● Possibile settare breakpoints breakpoint: punto del codice in cui l'esecuzione deve

fermarsi per poi reiniziarla

Page 6: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging con gdb● Eseguire un programma con gdb

gdb nome_binario Esce prompt dei comandi

(gdb)

● Settaggio della linea di comando

(gdb) set args opzioni_da_linea_di_comando

● Settaggio breakpoint

(gdb) break nome_file.cc:numero_linea Esempio

(gdb) break operator_streams.cc:10

Page 7: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging con gdb● Esecuzione (si ferma a breakpoint)

(gdb) run Se ridigitato si reinizia l'esecuzione dall'inizio

● Esecuzione fino a punto specificato

(gdb) until nome_file.cc:numero_linea Esempio

(gdb) until operator_streams.cc:20

Page 8: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging con gdb● Esecuzione passo-passo (esegue 1 riga di codice)

Esegue prossima riga nel flusso del programma Non necessariamente la riga successiva sul file.cc Se chiamata funzione, entra in funzione

(gdb) step

● Stampa dello stack (per vedere catena chiamata funzioni nel punto attuale)

(gdb) backtrace Possibile avanzare in alto o basso sullo stack

(gdb) up (gdb) down

Page 9: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging con gdb● Print di una variabile

(gdb) print nome_variabile Esempio

print el

● Display di una variabile Display è un print permanente La variabile è stampata sullo schermo ogni volta che

l'esecuzione si arresta

(gdb) display nome_variabile

● Per uscire digitare quit o cntr-D

Page 10: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging di errori di memoria● Errore provoca un segmentation fault, MEMFLT

In genere provocato da una errata gestione della memoria

SOLUZIONE 1 Compilare il programma con opzione -g Rieseguire il programma per generare il core file

(settando ulimit -c unlimited) Analizzare il core file con un debugger come gdb

Page 11: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e core files● Core file è un dump dello stato della memoria usata

da un binario Nome da quando memoria era un core magnetico Generabile in qualsiasi momento con una chiamata di

sistema nei sistemi UNIX Tipicamente viene generato in caso di un fault (di

memoria o altro tipo) Per abilitare la generazione

ulimit -c unlimited

Se il binario usa molta memoria file può essere grande Dal core file possibile a posteriori analizzare il fault

Page 12: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Core files e gdb● gdb permette di analizzare il core file

gdb nome_binario core_file

Una volta aperto il gdb permette di analizzare la memoria. Esempio per vedere il punto in cui è avvenuto l'errore

(gdb) backtrace O andare up nello stack e verificare valore di variabili

(gdb) up

(gdb) print el

Page 13: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Valgrind è un tool open-source per l'analisi del

software Scaricabile liberamente da

http://valgrind.org O tramite pacchetto della distribuzione Linux usata Nato come tool per fare check della memoria

Page 14: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Valgrind è nato come tool per fare check della

memoria Oggi fa molto di più (vedremo cosa sono queste cose)

CPU e mem profiling, Cache profiler Race condition in codice Multi-threaded

● Valgrind usa una macchina virtuale con compilazione al volo (just-in-time)

Codice da eseguire viene tradotto in un linguaggio intermedio, poi riconvertito in codice da eseguire

Codice tradotto è tracciabile e monitorabile

Page 15: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Valgrind è supportato da Linux e Mac OS X

● Prezzo da pagare per la traduzione: Codice gira qualche decina di volte più lento che il

binario originale Uso della memoria aumenta di molto Difficile fare debugging di errori che avvengono dopo

un lungo tempo di esecuzione

Page 16: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Valgrind è il miglior metodo per analizzare i bug

NONDET Trova errori dovuti ad uso di memoria non inizializzata Mappa tutte le celle di memoria usate come

inizializzate o no Genera errore se si accede a memoria non inizializzata Usa tanta memoria e CPU aggiuntiva per fare questo

● Trova inoltre bug dovuti a deallocazione di memoria non allocata Accesso out-of-boundary in vettori od a memoria non

allocata in generale

Page 17: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Vantaggio fondamentale nell'uso dei memcheck

Debuggers trovano errore quando avviene il fault Valgrind trova l'errore appena avviene, esempio1:

int* v = new int[7];

for (i=0; i<15;++i) v[i] = 1; // ma v=new int[7];

Il fault avviene appena si esce dal boundary Sia GDB che Valgrind lo tracciano

Memoria non allocata

scorro vettore Out-of-boundary, Segmentation Fault!

Page 18: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Caso 2

int* v = new int[7]; int* w = new int[7];

for (i=0; i<15;++i) v[i] = 1;

Compilatore ha messo il vettore v e w accanto! Non garantito ma probabile, succeda. Per ottimizzare

caching, SO alloca vicino aree di memoria del processo! Segmantation Fault non avviene finché non si esce anche

da w, ma l'esecuzione è sbagliata e spesso non deterministica!

Memorianon allocata

scorro vettore Non vadoout-of-boundary

Solo quiout-of-boundary

Page 19: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Debugging e Valgrind● Il fault non è nemmeno detto avvenga (ad esempio

se il loop si ferma a 10) Ma il programma era sbagliato! In generale tracciano il Fault con GDB si trova il primo

fault, ma non la sorgente iniziale dell'errore! Valgrind traccia esattamente le allocazioni:

v → [v, v+7*sizeof(int)] Ad ogni accesso in memoria v[i], controlla se si cade

nel range [v, v+7*sizeof(int)] Se non succede ottenete un warning per ogni accesso

non coretto alla memoria

Page 20: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Valgrind: memcheck, uso● Valgrind usa convertitore, pertanto non serve

modificare la compilazione Tranne usare l'ozione -g del g++ perché Valgrind dia

messaggi più informativi Uso

valgrind –tool=memcheck nome_binario argomenti

Page 21: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Valgrind: memory leaks● Valgrind può tenere traccia della memoria allocata e

non più raggiungibile e mai deallocata Traccia tutte le allocazioni fatte e verifica se la

memoria allocata è accessibile tramite un puntatore Da messaggio di errore se non succede e conta la

quantità di memoria persa Uso

valgrind –tool=memcheck –leak-check=yes nome_binario args

Page 22: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Valgrind: controllo uso cache● Programmi che usano le cache di basso livello sono

più veloci Usare una struttura dati od un'altra possono cambiare

il tasso di cache hit Ma come analizzare tutto questo? In generale è

nascosto al programmatore Valgrind fornisce uno strumento per controllare il

numero di accessi alle cache di diverso livello Uso

valgrind –tool=cachegrind nome_binario args

Page 23: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

CPU e mem profilers● Talvolta il software non presenta bags ma è troppo

lento od usa troppa memoria Come ottimizzare il consumo di memoria e CPU

● Intanto, REGOLA 1 dell'ottimizzazione del codice Non ottimizzare il codice presto

Inizialmente cura il design e la flessibilità Ad esempio, non rinunciare mai a fare un metodo virtual

Ultimo passo: ottimizza DOVE SERVE Il CPU o MEM profiler ti dicono dove val la pena di farlo

Page 24: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

CPU profiler: funzionamento● Funzionamento basato su sampling

Ogni x millisecondi, si chiede al binario di fornire il suo stack

Stack fornisce la funzione in cui ci si trova, da chi si è chiamati, ecc.

La percentuale di volte in cui il sampling ha trovato che ci si trova in una funzione approssima la CPU usata dalla stessa

Possibile anche contare il numero di volte che si segue un path rispetto ad un altro

Page 25: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

MEM profiler: funzionamento● Funzionamento basato su ridefinizione della libreria

che gestisce le allocazioni di memoria Non si chiama new, delete di sistema ma quelle

definite in libreria aggiunta in linking Le librerie aggiunte per il profiling in genere

Tracciano la funzione che chiama l'allocatore o deallocatore

Passano la chiamata all'allocatore o deallocatore di sistema

Si paga una penalità in performance, i binari su cui si fa il profiling sono più lenti

Aggiungere le librerie solo quando si ottimizza il codice

Page 26: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gprof● Strumento per effettuare cpu profiling integrato con

g++, con utilizzo molto semplice In compilazione e linking usare le opzioni -g e -pg Eseguire il programma → genera file gmon.out Per analizzare il file di output

gprof nome_programma gmon.out Stampa profilo testuale

Page 27: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gprof● Profile testuale ottenuto ha formato

% cumulative self self total time seconds seconds calls ms/call ms/call name 33.34 0.02 0.02 7208 0.00 0.00 open 16.67 0.03 0.01 244 0.04 0.12 offtime 16.67 0.04 0.01 8 1.25 1.25 memccpy 16.67 0.05 0.01 7 1.43 1.43 write 16.67 0.06 0.01 236 0.00 0.00 tzset 0.00 0.06 0.00 192 0.00 0.00 tolower 0.00 0.06 0.00 47 0.00 0.00 strlen 0.00 0.06 0.00 45 0.00 0.00 strchr 0.00 0.06 0.00 1 0.00 50.00 main 0.00 0.06 0.00 1 0.00 0.00 memcpy 0.00 0.06 0.00 1 0.00 10.11 print 0.00 0.06 0.00 1 0.00 0.00 profil 0.00 0.06 0.00 1 0.00 50.00 report

Page 28: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

google-perftools: introduzione● Strumento per effettuare cpu e mem profiling

Liberamente scaricabile (utilizzabile senza restrizioni) da

http://code.google.com/p/google-perftools/

Istallazione

./configure

make

make install

Page 29: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

google-perftools: utilizzo CPU ● In Linking

aggiungi -lprofiler

● In esecuzioneCPUPROFILE=/tmp/mybin.prof binario_con_cprofiler_linkato

● Per analizzare l'output

pprof --text binario /tmp/mybin.prof o in modalità grafica (richiede dot e ghostview):

pprof --gv binario /tmp/mybin.prof

Page 30: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

google-perftools: utilizzo MEM ● In Linking

aggiungi -ltcmalloc

● In esecuzioneHEAPPROFILE=/tmp/mybin.prof binario_con_mprofiler_linkato

● Per analizzare l'output

pprof --text binario /tmp/mybin.prof o in modalità grafica (richiede dot e ghostview):

pprof --gv binario /tmp/mybin.prof

Page 31: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

google-perftools: output● Modalità testuale, collezione di linee

14 2.1% 17.2% 58 8.7% std::_Rb_tree::find

... numero samples la funzione era ultima sullo stack % samples in cui si era nella funzione (% volte la

funzione era ultima sullo stack) % of profiling samples in the functions printed so far numero samples la funzione era sullo stack % di profiling samples nella funzione e nelle funzioni

chiamate (% volte che la funzione era sullo stack) Nome della funzione

Page 32: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

google-perftools: output● Modalità grafica

Page 33: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Valgrind: mem profiling● Anche Valgrind ha strumento per l'analisi dell'uso

della memoria Controlla periodicamente l'uso della memoria Possibile tracciare come aumenta nel tempo e chi la

richiede Uso

valgrind –tool=massif nome_binario args

Page 34: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Sommario● Testing

La correttezza del software Tipi di test Esercizi con libreria gtest

● Debugging Tecniche Strumenti

gdb valgrind

Esercizi

Page 35: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Testing di correttezza● Analisi di correttezza di un modulo o intero sistema

Esecuzione di singoli casi (test case) Confronto risultato con valore atteso

● Esecuzione non corretta risulta in failure Permette di scoprire gli errori (bugs/defect/fault) Porta il software ad un livello di qualità accettabile

Non vuol dire perfezione

Page 36: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

La correttezza del software● Assiomi del testing

Non possibile testare un programma in modo completo Dimostrare correttezza vuol dire testare tutte le coppie

input/output Input space troppo ampio Stato interno dei programmi ampio Numero di possibili esecuzioni enorme Specifiche sono spesso interpretabili in modo soggettivo

Page 37: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

La correttezza del software● Esempio, dimostrare correttezza di

int func(int x, int y) { return x + y; }

Necessario testare tutte le combinazioni (x,y) Se un int è 4 byte 232 * 232 = 264 casi da testare!

Page 38: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

La correttezza del software● Se si testano solo alcuni input, spesso non possibile

testare tutti i cammini (path) che segue il codiceint func(int x, int y) { for (int i = 0; i < n; ++i) if (a[i] == b[i/2]) a[i] += 100; else b[i] /= 2;}

a e b vettori di dimensione 100

2 path ad ogni loop, ma il path scelto influenza i path successivi

Numero path possibili sull'intera esecuzione è 2n

Page 39: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

La correttezza del software● Software testing è un processo risk-based

Più test ci sono più probabile che il software sia corretto

Non possibile provare correttezza Possibile ci siano altri bug Più bug sono stati trovati, più probabile ce ne siano

altri In generale, necessario trovare un compromesso tra

costo del testing e benefici attesi

Page 40: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

La correttezza del software● Software testers

Spesso non amati come componenti dei teams Chi programma pensa che blocchino sviluppo e

creatività Non vero! Testing richiede creatività e professionalità, oltre

capacità ben specifiche Senza competenze specifiche impossibile creare test

efficaci nel scovare bugs

Page 41: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Test di correttezza: diversi livelli● Unit testing: test di singoli moduli software (spesso

una singola classe) Black box testing: basati sulle specifiche. In caso di

classi testando l'interfaccia pubblica della classe White box testing: basati sulla logica interna. Il test è

friend del test Gray box testing: una mistura dei precedenti

● Integration testing: test dell'integrazione tra moduli● System testing: test a livello di sistema

Page 42: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Altri tipi di test● Performance testing: test del tempo e risorse

necessarie per svolgere un certo task● Stress testing: test nel caso di chiamate ripetute o

concorrenti ad un certo task Fondamentale per codice che gira su servers

● Regression testing: controlla che un cambiamento nel codice non introduce nuovi bug o problemi

Alla base resta un test di correttezza: basato su unittesting

Ma può essere necessario aggiungere integration e performance testing

Page 43: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Unittesting● Meccanismo di basso livello ma fondamentale per il

successo del testing Importante che ogni modulo e classe abbia test

associato Basato su un insieme di test cases Primo passo per realizzare Regression Testing Disponibili librerie per supportare l'implementazione ed

esecuzione degli unittest Dette Test Management Libraries Le studieremo

Page 44: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Integration e System testing

● Realizzabile bottom-up Si testano i singoli moduli con unittesting e poi gruppi

di moduli sempre più grandi fino all'intero sistema

● Top-down Si testa l'intero sistema e poi gruppi di moduli fino ai

singoli moduli con unittesting

Page 45: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Test nello sviluppo del software

● Test processo complesso che va dal design,

all'implementazione ed all'esecuzione● Test sono eseguiti durante l'implementazione di una

classe/modulo per controllare stato Sempre prima di effettuare svn commit!

Test DesignTest

ImplementationTest

ExecutionResults

Verification

Test ManagementLibrary

Page 46: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

Test ed automazione

● Consigliabile automatizzare l'esecuzione dei test

Eseguiti in modo regolare automaticamente per controllare stato del codice nel repository

Possibile anche automatizzare eseguzione test in svn, evita commit di codice che rompe i test

Test DesignTest

ImplementationTest

ExecutionResults

Verification

AutomatizzazioneTest ManagementLibrary

Page 47: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest● Libreria open-source in C++ inizialmente realizzata

da Google Detta googletest o gtest Scaricabile da

http://code.google.com/p/googletest/

Utilizzabile liberamente in ogni contesto (anche industriale)

Rende facile la creazione di test ed il loro monitoraggio

Page 48: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest● Google Test si basa sul concetto di assertion,

controllo che una condizione sia verificata Assertion può essere fatale (fatal), se blocca

esecuzione del test o non fatale se il test continua Se possibile, usare le non fatali, il programma continua

e si ottiene sommario finale dell'andamento del test

● Test è un insieme di assertions● Test case è un gruppo di test che condividono

strutture dati e concetti● Programma di test contiene più test cases

Page 49: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e test case● Test case è una funzione

TEST(NomeTestCase, NomeTest) { … }

● Più test associati a stesso test case, formano un test case

TEST(NomeTestCase, NomeTest1) { … }

TEST(NomeTestCase, NomeTest2) { … }

TEST(NomeTestCase, NomeTestN) { … }

● Intero programma è test program

Page 50: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e assertions● Vi sono tanti modi di scrivere assertions, prendono

due argomenti che devono rispettare la condizione Con terminazione del programma

ASSERT_TRUE(bool); ASSERT_FALSE(bool);

Senza terminazione EXPECT_TRUE(bool); EXPECT_FALSE(bool);

Esempio ASSERT_TRUE(ptr != NULL);

Page 51: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e assertions● Vi sono tanti modi di scrivere assertions, prendono

due argomenti che devono rispettare la condizione Fatali

ASSERT_EQ(arg1, arg2) ASSERT_GT(arg1, arg2) ASSERT_GE(arg1, arg2) ASSERT_NE(arg1, arg2)

Non fatali EXPECT_EQ(arg1, arg2) EXPECT_GT(arg1, arg2) EXPECT_GE(arg1, arg2) EXPECT_NE(arg1, arg2)

Page 52: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e main● Il main del test deve chiamare le funzioni

::testing::InitGoogleTest(&argc, argv);

return RUN_ALL_TESTS();

● La seconda funzione esegue tutti i test

Page 53: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest: esempio Test

TEST(IntegerTest, OperatorIncrement) {

Integer i(5);

++i;

EXPECT_EQ(6, i.Get());

}

● Vediamo ora l'implementazione completa di un test: operator_test.cc

Page 54: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest: white box testing● White box testing richiede che test sia friend● gtest permette questo nel seguente modo

nella definizione della classe testata

#include "gtest/gtest_prod.h" // necessario includere gtest!class ClasseDaTestare { FRIEND_TEST(NomeTestCase, NomeTest); … /* implementazione classe */};

nel test

TEST(NomeTestCase, NomeTest) { ClasseDaTestare c; EXPECT_EQ(0, c.a); // a dato privato di c}

Page 55: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e classi● Talvolta ci sono operazioni da fare all'inizio e fine di

ogni test Ripeterle ogni volta poco elegante Se non fatte si rischia che il test non sia valido gtest permette di definire queste operazioni in modo

consistente Test Fixture: classe figlia di ::testing::Test; Contiene oggetti che si vuole usare per composizione Implementare metodo SetUp per definire cosa fare ad

inizio test Implementare metodo TearDown per definire cosa fare a

fine test Chiamare TEST_F() per fare test usando Fixture

Page 56: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e Test Fixture: esempioclass IntegerTestWithFixture : public ::testing::Test {protected: Integer i; virtual void SetUp() { // chiamato prima di ogni test i = Integer(5); } // virtual void TearDown() {} // chiamato dopo ogni test};// Lista di singoli TestTEST_F(IntegerTestWithFixture, Constructors) { EXPECT_EQ(5, i.Get());}TEST_F(IntegerTestWithFixture, OperatorEqual) { Integer j(0); j = i; EXPECT_EQ(5, j.Get());}

Page 57: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e Test Fixture● Anche con Fixture possibile dichiarare i singoli test

friend nella classe da testare

● Oppure dichiarare l'intera classe come friend

class Integer {

friend class IntegerTestWithFixture;

// Implementazione della classe

}

Page 58: Debugging e Testing del Software - unisi.itDebugging.pdf · 2018-06-06 · Debugging e Testing del Software Michelangelo Diligenti Ingegneria Informatica e dell'Informazione diligmic@diism.unisi.it

gtest e classi: esercizi● Esercizio 1: testare la classe Integer attraverso

gtest (lo facciamo insieme)● Esercizio 2: testare la classe Integer attraverso

gtest con Fixture (lo facciamo insieme)● Esercizio 3: testare una classe Lista● Esercizio 4: testa la classe Matrix