Strumenti per la verifica
            automatica dei programmi




Linguaggi dinamici – A.A. 2009/2010
                                         1
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
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
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
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
Unit Testing




Linguaggi dinamici – A.A. 2009/2010
                                                6
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
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
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
Un scenario di uso (JUnit, Java)




Linguaggi dinamici – A.A. 2009/2010
                                           10
Un esempio di report




Linguaggi dinamici – A.A. 2009/2010
                                             11
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
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
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
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
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
Strumenti per il debugging
                     p          gg g




Linguaggi dinamici – A.A. 2009/2010
                                        17
First Computer bug (1)




Linguaggi dinamici – A.A. 2009/2010
                                             18
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Debugger a finestra
 Comandi per
 eseguire
 passo passo                          Ispezione
                                      delle variabili




Breakpoint




Linguaggi dinamici – A.A. 2009/2010
                                                        49
Debugger a finestra
                                       Ispezione
                                       delle variabili

   Stack delle
   chiamate




Breakpoint




Linguaggi dinamici – A.A. 2009/2010
                                                         50

T8 supporti

  • 1.
    Strumenti per laverifica 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
  • 6.
    Unit Testing Linguaggi dinamici– A.A. 2009/2010 6
  • 7.
    Funzionalità offerte dalloUnit 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 diuso (JUnit, Java) Linguaggi dinamici – A.A. 2009/2010 10
  • 11.
    Un esempio direport 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 perla 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 perla 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 ildebugging p gg g Linguaggi dinamici – A.A. 2009/2010 17
  • 18.
    First Computer bug(1) Linguaggi dinamici – A.A. 2009/2010 18
  • 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 deivalori 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 didebugging 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 inPython 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 inPython 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 primaistruzione 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 SSi 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 albreakpoint 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 inRuby 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 inPerl 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 inPerl 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 Eseguela 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