...

Software Engineering

by user

on
Category: Documents
14

views

Report

Comments

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
Fly UP