Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
LA VERIFICA DEL SOFTWARE (TESTING)
stiamo rispettando i requisiti di sistema, ha piu a che fare con i requisiti dell’utente
- Validazione:
- Verifica: stiamo costruendo software in modo corretto (far emergere e correggere bug)
Classificazione test:
1. Test dello sviluppo (verifica) : condotto da sviluppatori per scoprire bug.
2. Test della Release(validazione): per verificare sistema soddisfa requisiti utente, a carico di team
apposito che prova una versione completa del sistema.
3. Test degli utenti (validazione): utenti provano il sistema nel loro ambiente.
Test Drive Developmnet (TDD)
Inizialmente nata con XP, si interlaccia lo sviluppo e la verifica del codice. Richiede un ambiente di testing
automatica come Junit.
Bisogna rispettare 3 regole:
pro: aiuta a fare chiarezza, assicura copertura del codice, permette test di regressione (verifico che il
codice che scrivo per la mia nuova funzionalita non intacchi la roba che ho gia scritto), semplifica
debugging, fornisce documentazione.
Contro: impraticabile quando si riusano grossi componenti o sistemi ereditari, inefficace con sistemi multi-
thread.
Test di sviluppo
- Test delle unità: provate singole unità di programma o classi di oggetti per verificare le funzionalità
di oggetti e metodi
- Test dei componenti: (Integration testing) , integrati più unità di programma per verificare le
interfacce dei componenti
- Test del sistema: integrati alcuni o tutti i componenti per verificare le interazioni tra i componenti
(si integrano anche componenti sviluppati da diversi teams).
Test delle unità
Testate le componenti di un programma come metodi o le classi. Testare una classe significa provarla con
diversi test cases, i test cases hanno input e output.
Come progettare test cases: esaminando strutture locale, esercitando tutti i cammini indipendenti della
struttura di controllo del metodo, esercitando tutti i cammini per la gestione degli errori del metodo,
provando le condizioni limite, provando il flusso dei dati attraverso l’interfaccia del metodo.
Test di classe riguarda attributi e metodi della classe, l’ereditarietà complica il testing, per esempio se un
metodo X di una superclasse funziona correttamente nel contesto di X ma erroneamente per le sottoclassi,
occorre testare X nel contesto di ogni sottoclasse.
Il test di una classe richiede:
- Driver: programma principale
- Stub: moduli gerarchicamente inferiori (hanno stessa interfaccia della classe che devo testare ma una
logica molto semplificata).
Se driver e stub sono onerosi il testing va rimandato fino al test di integrazione (magari ho dipendenze della
classe che voglio testare con moltissima roba allora il test di unità è troppo oneroso)-
I moduli fittizzi inseriti per testare sono deviniti mock. (come per esempio usare un array per simulare un
database).
Metodologie di identificazione dei test cases:
-black box (funzionale): basato sulle specifiche del modulo/sistema considerato, garantisce il rispetto dei
requisiti ed è condotto dall’interfaccia esterna. Identifica anche cose che magari mancano nel codice ma sono
presenti nei requisiti.
- white box (strutturale): basato sul codice del modulo considerato, casi di prova ricavati dalla struttura di
controllo, può garantire che tutti i cammini indipendenti in ciascuna unità di programma siano eseguiti.
WHITE BOX TESTING
Static testing: senza eseguire il codice
Code complexity: misura complessita logica del codice e da un limite superiore al numero di test da fare.
Unit coverage: misura di quando il codice di unità provato dalla suite di test è coperto
- Function coverage: è stat richiamata ogni funzione del programma?
- Statement coverage: sono state eseguite tutte le istruzione del programma?
- Path coverage (Branch coverage): ogni ramo di ciascuna struttura di controllo è stato eseguito? Per
esempio se ho un if, sono stati eseguiti entrambi i rami true e false?
- Condition Coverage: ogni sottoespressione booleana è stata valutata sia quando vera che falsa?
(sono quelle all’interno di if, while ecc..)
Per ciascuna di queste misure si possono ricavare dei test case, anche dalla code complexity. Vediamo
come:
ci serve prima Flow Graph: grafo che rappresenta la struttura del porgramma
Regione!
Se if else è l’ultima parte del mio grafo metto lo stesso il nodo finale fittizio giusto per finire da qualche
parte.
Regione: regione del flow graph delimitata da nodi e archi
Cammini indipendenti: attraversa almeno un arco che non è stato attraversato dai cammini precedenti.
Complessita ciclomatica: misura quantitativa della complessità logica di un programma, la complessità
aumenta quanto un modulo è soggetto a errori. Un sinsieme di cammini indipendenti è una base per un
programma se è il più grande possibile e l’unione dei cammini copre il flow graph del programma. La
complessità cilcomatica è il numero di cammini indipendenti nell’insieme base di un programma.
Fornisce il limite superiore per il numero di test da condurre per garantire che tutte le istruzioni siano
eseguite almeno una volta e ogni condizione verificata.
Come calcolare complessità ciclomatica(3 modi diversi):
I nodi predicato sono quelli che rappresentano decisioni logiche, come if, while, for, switch, ecc..
Testing per cammini base:
1. Tracciare il flow graph
2. Calcolo complessità ciclomatica
3. Determino una base di cammini linearmente indipendenti
Preparare i test case che portano all’esecuzione di tutti i cammini nella base (scelgo i dati in modo
4. che le condizioni dei nodi predicato siano impostate correttamente rispetto al cammino).
Esempio:
Ho 6 cammini indipendenti! Ora identifichiamo un test case per ogni cammino indipendente!
Testing per data flow
basato su una nozione di copertura del codice, seleziono alcuni cammini nel programma secondo la
posizione delle definizioni e degli usi delle variabili (X sono le variabili):
DEF(S) = X tale che l’istruzione S contiene una definizione di X
- USE(S) = X tale che l’istruzione S usa X
-
Una definizione di Z nell’istruzione S si dice nell’istruzione S’ se esiste un cammino da S a S’ che non
viva (DU) per la variabile X è [X,S,S’], dove X è in
contiene altre definizioni di X. Una catena definizione-uso
DEF(S) e USE(S’) e la definizoine di X è viva in S’.
Coprire ogni catena DU con un caso di testing.
Testing per condizione e testing per cicli
Condizione: progettazione di test case basato sulle condizioni logiche del programma, testare tute le
condizioni di un programma per garantire che non contengano errori.
Cicli: si concentra sulla validità dei costrutti di ciclo:
- Cicli semplici (n = numero massimo di esecuzioni):
1. Percorrere il ciclo 0,1,2 voltre (3 test case)
2. Percorrere il ciclo m volte con m minore di n (1 test case)
3. Percorrere il cilclo n-1,n,n+1 volte (3 test case)
- Cicli annidati
1. Fissare i cicli esterni ai valori minimi e testare quello più interno come un ciclo semplice
2. Procedere verso i cicli esterni mantenendo quelli ancora più esterni al minimo e quelli interni a
un valore tipico.
Ispezione del software (tecniche white box statica)
Non occorre eseguire il codice, completamente manuale. Applicata nel corso del progetto a tutti gli artefatti,
non solo al codice. Va fatta il prima possibile ma non troppo presto. Sono più efficaci dei test per scoprire i
difetti. Si segue una check list, risponendo a delle domande, per esempio:
TESTING BLACK BOX
Non si ha conoscenza sulla struttura interna del progremma, si considerano i requisiti funzionali di un
programma, fatto un po in tutto lo sviluppo e alla fine di esso rimane solo il black box testing. Rileva
errate o mancante, errori d’interfaccia, errori nelle strutture dei dati o negli accessi al database,
funzioni
errori di behaviour o prestazionali, errori di inizializzazione o terminazione.
Testing per classi di equivalenza
Suddivide il dominio dei dati di input in classi di equivalenza tali che il comportamento del modulo per ogni
istanza della classe è simile. (per esempio se ho come input numeri interi potrei avere le classi di equivalenza
dei numeri interi positivi e negativi).
Per identificare le classi di equivalenza consideriamo le condizioni di input:
Esempi classi di equivalenza:
Analisi dei valori limite( boundary value analysis)
Il maggior numero di errori tende ad accumularsi ai limiti delle classi di equivalenza piuttosto che al centro,
si seleziona un test case che contenga almeno un valore su ciascun versante della frontiera di una classe di
equivalenza. Ricordarrsi di includere test cases che rappresentano configurazioni non valide dei dati in
ingresso. Da usare insieme al testing per classe di equivalenza.
Linee guida:
Esempio:
altre linee guida (Whittaker)
scegliere input che forzano il sistema a generare tutti i messaggi d’errore
-
- progettare input che causano un overflow dei buffer di input
- ripetere lo stesso input o la stessa serie in input numerose volte
- forzare la produzione di output non validi
- forzare i calcoli in modo da ottenere valori molto grandi o molto piccoli
tiro fuori le condizioni di input e output da precondizioni e postcondizioni!
Testing ad array ortogonale
Si utilizza quando il dominio di input è relativamente ridotto ma troppo esteso per un testing esaustivo.
Quello che abbiamo visto fino ad ora si faceva spostando un input alla volta, così rilevando solo errori single
mode, ovvero quegli errori che dipendono dal valore in input di un parametro, non di più parametri insieme.
Con array ortogonale rilevo tutti gli errori single-mode, double-mode e alcuni multi-mode.
La tabella di verità è predefinita per il metodo ad array ortogonale, per esempio questo è L9, ovvero quando
ho 9 possibili combinazioni derivate da 4 parametri che assumono 3 valori, avessi un altro numero di
combinazioni mi serve un altro array ortogonale (basta cercare su internet per trovarli).
Test dei componenti
Moduli che singolarmente funzionano potrebbero non funzionare quando integrati, per esempio se ho un uso
errato delle interfacce, incomprensione delle interfacce, errori di tempistica. Il problema consiste
nell’interfacciamento tra moduli, testiamo l’interfaccia del componente composto.
Linee guida:
Stress test: geneare molti più messaggi di quelli che si avrebbero normalmente
Quando effettuare questo testing?
Big bang testing: alla fine dell’integrazione, quando il programma è gia costruito nella sua interezza,
destinata a fallire
Integration testing
Tecnica sistematica per costruire la struttura di un programma conducendo temporaneamente i test relativi
alle interfacce. Si puo fare top down, bottom up , per sistemi OO, testing per regressione