1. Strumenti per la verifica
automatica dei programmi
Linguaggi dinamici – A.A. 2009/2010
1
2. Testing del software
T I moderni linguaggi dinamici possono
introdurre diversi effetti collaterali per via delle
p
operazioni dilazionate a run time
T Tali effetti collaterali vanno controllati di
continuo con una attività automatica e costante
di verifica della correttezza di un software
T Il processo di verifica è concettualmente
semplice,
semplice ma lungo e tedioso
T È soggetto ad errori umani
T Non scala con le dimensioni del codice
T Va automatizzato!
Linguaggi dinamici – A.A. 2009/2010
2
3. Tipologie di test
T Functional (Unit) test: (molto frequente)
T Si verificano le funzionalità dei singoli moduli
T Integration (acceptance) test: (molto frequente)
T Si verificano le funzionalità di alto livello del
ifi l f i lità lt li ll d l
programma, di solito utilizzate dal cliente finale
T Regression test: (frequente in progetti grossi)
T Si verifica che le modifiche introdotte non
portino ad una regressione
T Si controlla la presenza di “bug” storici
g
T Performance (stress) test: (ambiente server)
T Si verifica il livello di prestazione del software
Linguaggi dinamici – A.A. 2009/2010
3
4. Benefici del testing
T Intercettazione dei malfunzionamenti a run time
( g)
(bug)
T Forma di documentazione del codice (API)
T Sviluppo incrementale
T Miglioramento del design di un software
T Facilitazione del refactoring
Linguaggi dinamici – A.A. 2009/2010
4
5. Unit Testing
T Meccanismo per verificare automaticamente le
funzionalità di un software
T I requisiti del software sono descritti tramite un
insieme di casi di studio (test cases)
T Ciascun test case è un insieme di funzioni che
mira ad invocare specifici servizi offerti da un
software
T Diversi test case che condividono lo stesso
Di it t h di id l t
obiettivo possono essere raggruppati in una
test it
t t suite
Linguaggi dinamici – A.A. 2009/2010
5
7. Funzionalità offerte dallo Unit Test
T Le funzioni dei test case non prendono in
ingresso alcun parametro, né forniscono in
g p ,
uscita alcun valore
T Sono delle vere e proprie “procedure”
procedure
T All'interno di ciascuna funzione di test, si
verifica se un risultato di una operazione è
coerente con un risultato atteso (asserzione,
assert)
T Alla fine di un test, viene stampato un
resoconto dettagliato
Linguaggi dinamici – A.A. 2009/2010
7
8. Asserzioni
T Una asserzione è una funzione che prende in
ingresso due (più comunemente, tre) parametri:
g (p , )p
T un oggetto calcolato da una funzione
T un oggetto contenente il risultato di riferimento
T una descrizione testuale del test
T L'asserzione verifica una data proprietà (ad es.,
L' i ifi d t i tà ( d
uguaglianza) fra l'oggetto calcolato e l'oggetto
di riferimento
if i t
T Se la proprietà vale, il test continua
T Se la proprietà non vale, il test si interrompe
Linguaggi dinamici – A.A. 2009/2010
8
9. Asserzioni
T Esempi di asserzioni comuni:
T assert_true():
assert true(): verità di una espressione booleana
T assert_equal(): uguaglianza di due espressioni
numeriche
T assert_not_equal(): disuguaglianza di due
espressioni numeriche
T assert_match(): uguaglianza di due stringhe
T assert_not_match(): disuguaglianza di due
stringhe
T assert_nil(): oggetto nullo
T assert_not_nil(): oggetto non nullo
Linguaggi dinamici – A.A. 2009/2010
9
10. Un scenario di uso (JUnit, Java)
Linguaggi dinamici – A.A. 2009/2010
10
11. Un esempio di report
Linguaggi dinamici – A.A. 2009/2010
11
12. Dettagli implementativi
T Nei linguaggi dinamici moderni, è presente un
modulo per lo Unit Testing
p g
T Junit (Java), Test::Simple (Perl), unittest
(Python), Test::Unit (Ruby)
T Ciascun test è implementato come una classe
con diversi metodi (uno per ciascun test case)
T La classe è figlia di una classe madre, che mette
a disposizione metodi per l esecuzione
l'esecuzione
automatica dei test
T I metodi eseguono operazioni ed asserzioni
Linguaggi dinamici – A.A. 2009/2010
12
13. Dettagli implementativi
T Una suite di test è implementata tramite una
classe a parte
p
T Lista di classi Unit Test
T Metodi a disposizione per l'esecuzione
l esecuzione
automatica dell'intera suite
T Metodi a disposizione per la generazione di
report riassuntivi nei formati più disparati (testo,
PDF,
PDF HTML)
Linguaggi dinamici – A.A. 2009/2010
13
14. Setup e Teardown
T Alle volte, occorre eseguire del codice prima di
p
procedere con l'esecuzione dei test veri e propri
p p
T Test::Unit mette a disposizione i metodi:
T setup: eseguito prima di ciascun test
(inizializzazione)
T teardown: eseguito dopo ciascun test (cleanup)
Linguaggi dinamici – A.A. 2009/2010
14
15. Best practices per la scrittura dei test
T Parte 1: verifica funzionale moduli (Unit Testing)
T Si parte da un programma già suddiviso in
moduli; se non lo è, occorre modularizzarlo
tramite un processo di refactoring
T Si testano tutti i moduli
T Si testano tutte le funzioni di un modulo
T In particolare, TUTTI gli input validi e non validi
T Gli input necessari ad attivare TUTTI i possibili
p
percorsi di codice (code path) all'interno di ogni
( p ) g
singola funzione
Linguaggi dinamici – A.A. 2009/2010
15
16. Best practices per la scrittura dei test
T Parte 2: verifica delle operazioni utente
(
(Acceptance Testing)
p g)
T Si identifica l'insieme di operazioni utilizzate più
frequentemente dall utente finale
dall'utente
T Per ciascuna operazione, si individua la relativa
sequenza di operazioni sui diversi moduli
T Si scrive un test case che emula il
comportamtento d ll' t t
t t t dell'utente
Linguaggi dinamici – A.A. 2009/2010
16
17. Strumenti per il debugging
p gg g
Linguaggi dinamici – A.A. 2009/2010
17
19. First Computer bug (2)
Moth found trapped between points at Relay # 70,
Panel F, of the Mark II Aiken Relay Calculator
, y
while it was being tested at Harvard University,
9 September 1945.
The operators affixed the moth to the computer
log, with the entry: "First actual case of bug
g, y g
being found".
They put out the word that they had "debugged"
yp y gg
the machine, thus introducing the term
"debugging a computer program".
Linguaggi dinamici – A.A. 2009/2010
19
20. Introduzione
T Cercare un bug significa confermare tutto
q
quello che noi supponiamo vero
pp
T La conferma avviene durante l'esecuzione
T Quando una nostra supposizione si rivela
sbagliata, abbiamo trovato un bug
T Esempi di supposizioni:
E i i i i
T suppongo che la variabile x valga 12
T suppongo che un oggetto sia stato istanziato
correttamente
T suppongo che in un if-then-else sia eseguito il
ramo else
Linguaggi dinamici – A.A. 2009/2010
20
21. Strategia di debugging
T Riconoscere l'esistenza del bug
(
(comportamento del sw non conforme alle
p
aspettative)
T Isolare la sorgente del bug (il frammento di
codice in cui il bug è contenuto)
T Determinare la causa del bug (riconoscere
l'errore logico che causa il bug)
T Applicare la correzione d l bug (agire sui
A li l i del b ( i i
sorgenti del programma)
T Verificare la correzione apportata (ogni modifica
al codice può introdurre nuovi errori)
Linguaggi dinamici – A.A. 2009/2010
21
22. Metodi di debugging
T Eseguire debugging significa esaminare il
comportamento interno del software, per
software
verificare che sia conforme alle nostre
suppos o
supposizioni
T Occorre esporre gli stati intermedi di
esecuzione del programma
T Due metodi:
T Debugging mediante stampa d i valori
D b i di dei l i
T Debugging mediante debugger
Linguaggi dinamici – A.A. 2009/2010
22
23. Stampa diretta dei valori
T PRO
T facile
T utile per sw di piccole dimensioni
T utile se si hanno sospetti sulla causa del bug
T CONTRO
T occorre modificare i sorgenti
T occorre ricompilare i sorgenti modificati
T si espongono solo poche informazioni, definite a
tempo di compilazione (procedimento iterativo)
T difficile da usare per sw di grandi dimensioni
T difficile d
diffi il da usare se non si hanno già sospetti
ih ià tti
Linguaggi dinamici – A.A. 2009/2010
23
24. Debugger
T Un debugger è un programma che può:
T eseguire altri programmi
T bloccarne l'esecuzione in ogni momento
T esaminare i valori contenuti nelle variabili
T eseguire programmi “riga per riga”
T esaminare lo stato dello stack
T Tutti i debugger (sia testuali che grafici)
svolgono le medesime operazioni
T “You see one you ve seen ’em all ”
You one, you’ve em all.
Linguaggi dinamici – A.A. 2009/2010
24
25. Debugger
T PRO
T non occorre modificare il sorgente
T non occorre ricompilare i sorgenti
T possono esporre tutte le informazioni utili
T utilizzabili su sw di grandi dimensioni
T utilizzabili per individuare le sorgenti dei bug
T CONTRO
T richiedono la conoscenza del debugger
T sovradimensionati per sw di piccole dimensioni
T sovradimensionati se si hanno già fondati
sospetti sulla causa del bug
tti ll d lb
Linguaggi dinamici – A.A. 2009/2010
25
26. Tipico ciclo di debugging del codice
T Invocazione del debugger
T Salto alla prima istruzione utile del programma
T ignorare le definizioni di classi/metodi/funzioni
T Listato del codice sorgente
T cosa sarà eseguito a breve
g
T Impostazione dei punti di interruzione
T breakpoint – dove bisogna fermarsi
T Esecuzione fino al breakpoint
T Analisi dello stato interno
T variabili
Linguaggi dinamici – A.A. 2009/2010
26
27. Debugging integrato in Python
T Uso del modulo pdb
T Uso da li
U d linea di comando:
d
T python -m pdb fatt.py
T -m cerca e carica il modulo pdb
T Interfaccia a linea di comando
T h(elp) fornisce una panoramica dei comandi
S Senza argomenti stampa la lista dei comandi
argomenti,
disponibili
S Con un comando command come argomento
argomento,
stampa l'help del comando
Linguaggi dinamici – A.A. 2009/2010
27
28. Debugging integrato in Python
T Viene aperta una shell con prompt (Pdb)
> fatt.py(1)<module>()
-> def fatt (n):
(Pdb) step
> fatt py(6)<module>()
fatt.py(6)<module>()
-> a = 3;
(Pdb) step
> f tt (7)< d l >()
fatt.py(7)<module>()
-> f = fatt(a);
(Pdb) step
--Call--
> fatt.py(1)fatt()
-> def fatt (n):
( )
(Pdb) step
> fatt.py(2)fatt()
-> if (n == 2 ):
Linguaggi dinamici – A.A. 2009/2010
28
29. Salto alla prima istruzione utile
T Si utilizza il comando next
T abbreviabile tramite il comando n
T salta tutte le definizioni di classi e funzioni
T Se invocato all'inizio del processo di
debugging, salta di fatto alla prima istruzione
utile del programma
T Se invocato nel mezzo di un programma,
p g ,
esegue lo statement attuale
T esegue in un sol colpo le chiamate di funzione
T Per eseguire singole istruzioni, usare step (s)
Linguaggi dinamici – A.A. 2009/2010
29
30. Listato del codice
T Si utilizza il comando list
T abbreviabile tramite il comando l
T senza argomenti, stampa 11 linee attorno a
quella corrente
ll t
T l 5: stampa 11 linee di codice attorno alla linea 5
T l 5-8: stampa le linee dalla 5 alla 8
Linguaggi dinamici – A.A. 2009/2010
30
31. Impostazione dei breakpoint
S Si utilizza il comando break
[[filename:]lineno|function[,
[[filename:]lineno|function[ condition]]
S abbreviabile tramite il comando b
S con un argomento lineno, imposta in quella riga
del file corrente un break
S con un argomento function, imposta un break
alla prima istruzione eseguibile in quella funzione
S senza argomenti elenca i breakpoint impostati
S tbreak è un breakpoint temporaneo
Linguaggi dinamici – A.A. 2009/2010
31
32. Impostazione dei breakpoint
T Il programma, quando eseguito, si interromperà
alla linea corrispettiva
T È possibile impostare più punti di interruzione
in li
i linee diverse
di
Linguaggi dinamici – A.A. 2009/2010
32
33. Esecuzione fino al breakpoint
T Si utilizza il comando continue
T abbreviabile tramite il comando c o cont
T Il programma esegue fino al primo breakpoint
incontrato
i t t
T sperando che sia vicino all'errore
T Se non viene incontrato alcun breakpoint, il
p g
programma continua fino al suo termine
T È consuetudine vedere la linea in cui il
programma si è interrotto con l
Linguaggi dinamici – A.A. 2009/2010
33
34. Ispezione delle variabili
T Si utilizzano diversi comandi
T comando p: stampa espressioni, variabili
espressioni
T Di solito, l'ispezione delle variabili è molto utile
per rivelare un bug
i l b
T Altrimenti eseguiamo l'istruzione successiva:
T eseguendo singole funzioni in un passo (n)
T discendendo nelle funzioni (s)
fino a quando non si scopre l'errore
Linguaggi dinamici – A.A. 2009/2010
34
35. Ispezione dello stack
T È possibile ispezionare lo stack delle chiamate
di funzione (con i relativi parametri)
T Comando where
T abbreviabile tramite il comando w
bb i bil t it d
T Comandi up, down
T permettono di ispezionare i diversi frame di uno
stack
Linguaggi dinamici – A.A. 2009/2010
35
36. Altri comandi
S a(rgs)
S St
Stampa l li t d li argomenti della funzione
la lista degli ti d ll f i
S r(eturn)
S Continua l'esecuzione fino al termine della
funzione corrente
S q(uit)
S Esce dal debugger
Linguaggi dinamici – A.A. 2009/2010
36
37. Debugger integrato in Ruby
T Attivabile tramite l'opzione -r debug
T viene invocata la libreria di sistema d b
i i t l lib i i t debug
tramite una require
T ruby -r d b
b debug d b 1 b
debug1.rb
T Interfaccia a linea di comando
T help fornisce una panoramica dei comandi
Linguaggi dinamici – A.A. 2009/2010
37
38. Comandi
T n(ext)
T Salto alla prossima istruzione utile
T Senza entrare nelle funzioni
T s(tep)
T Salto alla prossima istruzione utile
T Entrando nelle funzioni
T l(list)
T l -10: stampa le precedenti linee di codice
T l 10: stampa le successive linee di codice
T l 10-20: stampa le linee 10-20
Linguaggi dinamici – A.A. 2009/2010
38
39. Comandi
T b(reak)
T Imposta un breackpoint
T b 6: imposta un punto di interruzione alla linea 6
T b: elenca i breakpoint impostati
T del 1: rimuove il breakpoint numero 1
T c(ont)
T Il programma esegue fino al primo breakpoint
incontrato
Linguaggi dinamici – A.A. 2009/2010
39
40. Ispezione delle variabili
T Si utilizzano diversi comandi
T comando p: stampa espressioni, variabili
espressioni
T comando v l: stampa tutte le variabili locali
T comando m <class>: stampa tutti i metodi di una
classe
Linguaggi dinamici – A.A. 2009/2010
40
41. Watchpoint
T È possibile interrompere il flusso del
programma se si verifica una specifica
condizione
T tipicamente,
tipicamente una variabile assume un
determinato valore
T Comando watch
T abbreviabile tramite il comando wat
T wat <condizione>
T wat @tmp=7
Linguaggi dinamici – A.A. 2009/2010
41
42. Catchpoint
T Solitamente, il debugger termina l'esecuzione
se il programma solleva una eccezione
T E' possibile interrompere il flusso del
programma se viene sollevata una eccezione
T Comando catch
T abbreviabile tramite il comando cat
T cat <eccezione>
Linguaggi dinamici – A.A. 2009/2010
42
43. Tracing
T È possibile stampare ciascuna riga eseguita dal
programma insieme al valore della espressione
corrispondente
T Comando trace
T abbreviabile tramite il comando tr
T tr on: attiva il tracing
T tr off: disabilita il tracing
Linguaggi dinamici – A.A. 2009/2010
43
44. Debugging integrato in Perl
T Attivabile tramite l'opzione –d
T perl -d program.pl
l d l
T Interfaccia a linea di comando
T h o h h fornisce una panoramica dei comandi
T Tutorial http://perldoc.perl.org/perldebtut.html
Linguaggi dinamici – A.A. 2009/2010
44
45. Debugging integrato in Perl
T Viene aperta una shell con prompt DB
main::(fatt.pl:11): $a = 3;
DB<1> s
main::(fatt.pl:12): $f = fatt($a);
DB<1> s
main::fatt(fatt.pl:3): my $n = shift;
DB<1> s
main::fatt(fatt.pl:4): if ($ == 2)
i f tt(f tt l 4) ($n
main::fatt(fatt.pl:5): {
DB<1> s
main::fatt(fatt.pl:8): return($n * fatt($n-1));
$ $
DB<1> s
main::fatt(fatt.pl:3): my $n = shift;
( ) y
DB<1>
Linguaggi dinamici – A.A. 2009/2010
45
46. Comandi
S h [command]
S S
Senza argomenti, stampa la lista dei comandi
ti t l li t d i di
disponibili
S C
Con un comando command come argomento,
d d t
stampa l'help del comando
S b [line|subname] [condition]
S Con un argomento line, imposta in quella riga del
file corrente un break
S Con un argomento subname, imposta un break
alla prima istruzione eseguibile in quella
subroutine
Linguaggi dinamici – A.A. 2009/2010
46
47. Comandi
S s Esegue la riga corrente
S n C ti
Continua l'esecuzione finché la prossima riga
l' i fi hé l i i
della funzione corrente non viene raggiunta o la
funzione termina
f i t i
S r Continua l'esecuzione fino al termine della
funzione corrente
S c Continua l'esecuzione, si blocca solo quando
, q
viene raggiunto un breakpoint
Linguaggi dinamici – A.A. 2009/2010
47
48. Comandi
S l [min+incr|min-max|line|subname]
S M t il codice sorgente del file corrente
Mostra di t d l fil t
S p expr
S Valuta l'espressione expression nel contesto
corrente e ne stampa il valore
S T Mostra lo stack delle chiamate
S q Esce dal debugger
Linguaggi dinamici – A.A. 2009/2010
48
49. Debugger a finestra
Comandi per
eseguire
passo passo Ispezione
delle variabili
Breakpoint
Linguaggi dinamici – A.A. 2009/2010
49
50. Debugger a finestra
Ispezione
delle variabili
Stack delle
chiamate
Breakpoint
Linguaggi dinamici – A.A. 2009/2010
50