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