Comments
Description
Transcript
Software Engineering
Defect testing L’obiettivo: scoprire difetti in un programma Un test ha successo se forza il programma a comportarsi in modo anomalo I test provano la presenza (non l’assenza) di errori: solo un testing esaustivo proverebbe l’assenza di difetti. 1 Priorità nel testing I test devono sondare le caratteristiche globali del sistema nel suo insieme più che le singole componenti Se il sistema è una nuova versionedi un sistema esistente, è più importante testare le vecchie caratteristiche che testare le nuove caratteristiche Testare le situazioni tipiche è più importante che testare i valori alla frontiera 2 Dati di test e casi di test Dati di test L’insieme di input che devono essere costruiti per testare il sistema Casi di test L’insieme di input per testare il sistema e gli output previsti in corrispondenza di questi input se il sistema soddisfa la sua specifica 3 Terminologia Per definire i Casi di Test devo adottare un criterio: Criterio C affidabile tutti i test selezionati da C hanno successo o nessuno lo ha Criterio C valido qualora P non sia corretto, $ un T selezionato C che ha successo 4 Esempio program RADDOPPIA ... .... read (x); y = x*x; write (y); ... Se C seleziona solo {0,2} è affidabile, non valido Se C seleziona tutti i sottoinsiemi di {0,1,2,3,4} è valido, non affidabile Se C seleziona insiemi che contengono tutti almeno un elemento < 3 è valido e affidabile 5 Elementi di teoria dei test Teorema di Goodenough e Gerhart Se Esiste un C affidabile e valido per P e T è selezionato da C e T non ha successo su P allora P è corretto 6 Elementi di teoria dei test Teorema di Howden Non si può costruire meccanicamente (mediante un programma) un test finito che soddisfi un criterio affidabile e valido 7 Il processo di defect testing Test cases Design test cases Test data Prepare test data Test results Run program with test data Test reports Compare r esults to test cases 8 Approcci al defect testing Testing team De velopment team Functional testing Interface testing Structural testing System Sub-system Unit and module 9 Black-box testing Approccio al testing in cui il sistema è visto come una “scatola nera” I casi di test sono basati sulla specifica del sistema La pianificazione può iniziare molto presto nel processo software 10 Black-box testing Input test data I Inputs causing anomalous behaviour e System Output test results Oe Outputs which reveal the presence of defects 11 Equivalence partitioning Invalid inputs Valid inputs System Outputs 12 Equivalence partitioning Partiziona gli input e gli output del sistema in “insiemi equivalenti” Se l’input è un intero di 5 digits tra 10,000 e 99,999, le classi di equivalenza sono: < 10.000 da 10.000 a 99.999 (compresi) >= 100.000 Scegli i casi di test ai confini di questi insiemi 0, 9.999, 10000, 99.999, 100.000, 150.000 13 Partizioni 3 4 Less than 4 7 11 10 Between 4 and 10 More than 10 Number of input values 9999 10000 Less than 10000 50000 100000 99999 Between 10000 and 99999 More than 99999 Input values 14 Specifica di una routine di ricerca procedure Search (Key : ELEM ; T: ELEM_ARRAY; Found : in out BOOLEAN; L: in out ELEM_INDEX) ; Pre-condition -- the array has at least one element T’FIRST <= T’LAST Post-condition -- the element is found and is referenced by L ( Found and T (L) = Key) or -- the element is not in the array ( not Found and not (exists i, T’FIRST >= i <= T’LAST, T (i) = Key )) 15 Partizioni di input Input che soddisfano le precondizioni Input dove una precondizione non vale Input dove l’elemento chiave è un membro dell’array Input dove l’elemento chiave non è un membro dell’array 16 Linee guida sul testing (arrays) Testare il programma con array che hanno solo un singolo elemento Usa array di dimensioni diverse nei diversi test Costruisci i test in modo che gli elementi primo, mediano e ultimo dell’array vengano visitati Testare il programma con array di lunghezza zero (se consentito dal linguaggio di programmazione) 17 Routine di ricerca: partizioni di input Array Single value Single value More than 1 value More than 1 value More than 1 value More than 1 value Element In array Not in array First element in array Last element in array Middle element in array Not in array 18 Routine di ricerca: casi di test Input array (T) 17 17 17, 29, 21, 23 41, 18, 9, 31, 30, 16, 45 17, 18, 21, 23, 29, 41, 38 21, 23, 29, 33, 38 Key (Key ) 17 0 17 45 23 25 Output (Found, L ) true, 1 false, ?? true, 1 true, 7 true, 4 false, ?? 19 Testing strutturale Chiamato talvolta white-box testing I casi di test sono ottenuti a partire dalla struttura del programma. La conoscenza del programma viene utilzzata per identificare altri ulteriori casi di test Obiettivo: vagliare tutti i comandi del programma (non tutti i cammini di computazione) 20 Criteri White-box Sono criteri di selezione dei casi di test basati su concetti di “copertura” della struttura interna del programma Congettura: se un programma è stato poco sollecitato dai dati di test, potenzialmente contiene anomalie Definito il livello desiderato di “copertura” è possibile valutare quanto progressivamente ci si avvicina all’obiettivo 21 White-box testing Test data Tests Derives Component code Test outputs 22 Copertura 1. Copertura delle istruzioni Obiettivo: esercitare almeno una volta ogni istruzione durante il test Motivazione: se no, ci possono essere computazioni scorrette o computazioni mai osservate 23 Esempio 1 Program statement (input, output); 5 2 var 3 x,y : real; 6 4 begin not(x>0) 5 read(x); 6 read(y); 8 7 if x > 0 then x:=x+10; 8 y:=y/x; 9 write(x); 9 10 write(y); 11 end. S = {(x = 20, y = 30)} soddisfa il criterio 10 read(x) read(y) x>0 x:=x+10 7 y:=y/x write(x) write(y) 24 Copertura 2. Copertura delle decisioni Ogni arco del flusso di controllo deve venire percorso S = {(x = 20, y = 30), (x = -3, y = 100} soddisfa il criterio Ma continua a non scoprire il malfunzionamento! 25 Arricchimento del criterio Utilizzare valori “ai limiti” dei campi di variabilità delle decisioni, oltre a valori “all’interno” Esempio se deve essere x >= 0, provare con x = 0, oltre che con x > 0 Attitudine “fare l’avvocato del diavolo” 26 Esempio 1 2 3 4 5 6 7 8 read (x,y); if x = 10 then x := x - 10 else x := |x| +1; if y <= 0 then y := (y+1)/x else y := x/y; ... T = {(10, 5), (0, -3)} copre tutte le decisioni Così facendo si coprono i cammini “then...else” e “else...then”, non il cammino “then...then” che genera un malfunzionamento. 27 Copertura 3. Copertura dei cammini Test strutturale esaustivo: tutti i cammini… ma il numero di cammini è infinito! Occorre limitare il numero: quali? Criteri empirici per limitare il numero delle iterazioni Il numero dei dati di test tende comunque a crescere in maniera non controllabile..... 28 Ricerca binaria (Ada) proce dure Bin ary_sea rch (Key: ELEM ; T: ELEM_ARRAY ; Foun d:in out BOOLEAN ; L: in out ELEM_INDEX ) is - Precond itio ns -- T’FIRST < =T’LAST and -- fo rall i: T’FIRST..T’LAST-1, T (i ) <= T(i+1 ) Bott : EL EM_ INDEX := T’FIRST ; Top : EL EM_ INDEX := T’LAST ; Mid : ELEM_INDEX; begin L := (T’ FIRST + T’L AST ) / 2; Fou nd := T( L ) = Key; while Bott <= Top and not Fo und loop Mid := (To p + Bott) mod 2; if T( Mi d ) = Key then Fou nd := tru e; L := Mid; els if T( Mi d ) < Key then Bott := Mi d + 1; els e Top := Mi d - 1 ; end if ; end loop ; end Bin ary_sea rch; 29 Ricerca binaria: partizioni di input Chiave nell’array Chiave non nell’array Array di input con un solo elemento Array di input con numero pari di elementi Array di input con numero dispari di elementi 30 Ricerca binaria: partizioni di input Equivalence class boundaries Elements < Mid Elements > Mid Mid-point 31 Ricerca binaria: casi di test Input array (T) 17 17 17, 21, 23, 29 9, 16, 18, 30, 31, 41, 45 17, 18, 21, 23, 29, 38, 41 17, 18, 21, 23, 29, 33, 38 12, 18, 21, 23, 32 21, 23, 29, 33, 38 Key (Key ) 17 0 17 45 23 21 23 25 Output (Fou nd, L) true, 1 false, ?? true, 1 true, 7 true, 4 true, 3 true, 4 false, ?? 32 Grafi di flusso del programma Descrivono il flusso di controllo nel programma usati per calcolare la complessità ciclomatica Complessità = Numero di archi - Numero di nodi +2 33 Rappresentazione di un grafo di flusso di un programma if-then-else loop-while case-of 34 1 (while Bott < = Top loop) 2 (if not Found then...) 3 4 (If T (mid) = Key then...) 5 6 7 8 (if T (mid) < Key then...) 9 10 12 11 13 35 Cammini indipendenti 1, 2, 3, 4, 12, 13 1, 2,3, 5, 6, 11, 2, 12, 13 1, 2, 3, 5, 7, 8, 10, 11, 2, 12, 13 1, 2, 3, 5, 7, 9, 10, 11, 2, 12, 13 1, 2, 3, 5, 7, 9, 10, 11, 2, 3, 4, 12, 13 Bisogna costruire dei casi di test in modo che tutti questi cammini siano percorsi Si può utilizzare un analizzatore dinamico per verificare che i cammini siano stati eseguiti 36 Complessità ciclomatica Il numero di test per controllare tutti i comandi di controllo è uguale alla complessità ciclomatica La complessità ciclomatica è uguale al numero di condizioni booleane nel programma E’ utile se usata con attenzione. Non è sempre adeguata come test e non può essere usata per programmi data-driven 37 Controllo e programmi data-driven case A is when “One” => i := 1 ; when “Two” => i := 2 ; when “Three” => i := 3 ; when “Four” => i := 4 ; when “Five” => i := 5 ; end case ; Strings: array (1..4) of STRING := (“One”, “Two”, “Three”, “Four”, “Five”); i := 1 ; loop exit when Strings (i) = A ; i := i + 1 ; end loop ; 38 Testare le interfacce Questo tipo di testing va fatto quando vengono integrati moduli o sottosistemi per creare sistemi più grandi L’obiettivo in questo caso è trovare errori dovuti alle interfacce o ad assunzioni sulle interfacce che non sono valide È particolarmente importante nello sviluppo object-oriented, in quanto gli oggetti sono definiti a partire dalle loro interfacce 39 Tipi di interfacce Interfacce realizzate con parametri I dati sono trasmessi da una procedura all’altra Interfacce a memoria condivisa Due o più procedure condividono la stessa memoria Interfacce procedurali Sottosistemi incapsulano un insieme di procedure che devono essere chiamate da altri sottosistemi Interfacce a passaggio di messaggi I sottosistemi richiedono servizi da altri sottosistemi 40 Testare le interfacce Test cases B A C 41 Errori nelle interfacce Cattivo uso delle interfacce Una componente chiamante chiama un’altra componente e commette un errore nell’uso dell’interfaccia di quest’ultima, ad esempio chiamando i parametri nell’ordine sbagliato Incomprensione di interfacce Una componente chiamante fa delle assunzioni sul comportamento della componente chiamata che non sono valide Errori di temporizzazione La componente chiamante e la componente 42 Linee guida per testare interfacce Progetta i test in modo che i parametri attuali delle procedure siano agli estremi del loro rango Testa sempre parametri di tipo riferimento con valore NIL Progetta test che causano il fallimento della componente Usa uno stress testing nel sistema di scambio di messaggi Nei sistemi a memoria condivisa, cambia l’ordine in cui le componenti sono attivate 43