Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Sergio Di Martino » 15.Strategie di Testing


Obiettivi della lezione

  • Comprendere le principali strategie di definizione di Test Cases
  • Strategia Black Box
  • Strategia White Box

Come testare una unità?

Dopo la creazione dello scaffolding siamo pronti a testare l’unità. Come procediamo?

Due strategie fondamentali:

  • Black Box: i test case sono derivati dalle specifiche di una unità. Non presuppone conoscenza del codice sorgente;
  • White Box: i test case sono derivati dalla struttura interna di una unità. Presuppone conoscenza del codice sorgente.

Testing Black Box

La definizione del casi di test e dell’oracolo è fondata sulla base della sola conoscenza dei requisiti specificati del sistema e dei suoi componenti. Strategia principale di generazione di casi di test …

  • E’ scalabile (usabile per i diversi livelli di testing).
  • Molte tecniche usabili sia per software tradizionale che OO.

Come definire l’insieme di test case? Per ogni funzionalità, effettuare un numero di esecuzioni dedotte dai dati di ingresso e di uscita, da precondizioni e postcondizioni. Definito il dominio dei dati di I/O effettuare test case ottenuti selezionando:

  • valori in posizione centrale;
  • valori ai bordi;
  • valori “speciali”.

Precondizioni e postcondizioni per test case:

  • positive;
  • negative (invalid input data, invalid output data);
  • neutrali.

… suddivisione dei test case in classi di equivalenza.

Classi di Equivalenza

Il problema: abbiamo un metodo, e vogliamo verificare che computi correttamente qualcosa, dati dei valori in input ai parametri

E’ chiaro che il dominio di input è normalmente troppo grande per un testing esaustivo dei valori.

Una funzione che prende in input due short richiederebbe 256×256 (=65.000!) test cases.

L’idea delle classi di equivalenza è di partizionare il dominio di input in un numero finito di sottoinsiemi in cui “ragionevolmente” il codice si comporta in maniera uniforme.

Se l’unità computa correttamente per un caso di test, si può dedurre ragionevolmente che è corretto per ogni caso di test in quella classe

Ogni sottoinsieme è una classe di equivalenza, e serve come base per almeno un input ad un test.

Come identificare le Classi di Equivalenza

Se la variabile di input è un intervallo di valori: almeno una classe valida per valori interni all’intervallo, una non valida per valori inferiori al minimo, e una non valida per valori superiori al massimo.

Es: supponiamo un parametro di input ad un metodo è usato per rappresentare il voto d’esame universitario.

  • La variabile ha senso nel range [18..30]
  • Definiamo 3 classi di equivalenza:
    • CE1 = valori ≥18 e ≤30 (classe di valori validi);
    • CE2 = tutti i valori < 18 (non valida) CE3 = tutti i valori >30 (non valida);
    • CE3 = tutti i valori >30 (non valida).

Come identificare le Classi di Equivalenza (segue)

Se la variabile di input è un elemento di un insieme discreto (enumerazione):

  • una classe valida per ogni elemento dell’insieme, una non valida per un elemento non appartenente;
  • include il caso di valori specifici;
  • include il caso di valori booleani.

Es: i colori di un semaforo
Definiamo 4 classi di equivalenza:

  • CE1 = “Rosso” (valida);
  • CE2 = “Giallo” (valida);
  • CE3 = “Verde” (valida);
  • CE4 = “Blu” (non valida).

Progettazione dei casi di test

Le classi di equivalenza individuate devono essere utilizzate per identificare casi di test che:

  1. minimizzino il numero complessivo di test;
  2. risultino significativi (affidabili).

Euristiche di base:

  • si devono individuare tanti casi di test da coprire tutte le classi di equivalenza valide, con il vincolo che ciascun caso di test comprenda il maggior numero possibile di classi valide ancora scoperte;
  • si devono individuare tanti casi di test da coprire tutte le classi di equivalenza non valide, con il vincolo che ciascun caso di test copra una ed una sola delle classi non valide.

Casi di test dalle classi di equivalenza

Supponiamo una funzione foo(a,b,c), che prenda tre variabili di input dei domini A, B, C.
Supponiamo di aver partizionato i domini in:

  • A = A1 ∪ A2 ∪ A3 dove an ∈ An
  • B = B1 ∪ B2 ∪ B3 ∪ B4 dove bn ∈ Bn
  • C = C1 ∪ C2 dove cn ∈ Cn

Criterio debole (Weak Equivalence Class Testing – WECT): scegli un valore per una variabile da ogni classe.

Criterio forte (Strong Equivalence Class Testing – SECT): verifica tutte le interazioni tra le classi (basato sul prodotto cartesiano dei sottoinsiemi delle partizioni A · B ·  C.

Casi di test con strategia WECT.

Casi di test con strategia WECT.

Casi di test con strategia SECT.

Casi di test con strategia SECT.


Esempio: NextDate

NextDate è una funzione con tre variabili: month, day, year. Restituisce la data del giorno successivo alla data di input tra gli anni 1840 e 2040. Specifica sommaria:

  • Se non è l’ultimo giorno del mese, la funzione incrementa semplicemente il giorno.
  • Alla fine del mese il prossimo giorno è 1 e il mese è incrementato.
  • Alla fine dell’anno, giorno e mese diventano 1 e l’anno è incrementato.
  • Considerare il fatto che il numero di giorni del mese varia con il mese e l’anno bisestile

Classi di Equivalenza:

  • M1 = {mese: il mese ha 30 giorni}
  • M2 = {mese: il mese ha 31 giorni}
  • M3 = {mese: il mese è Febbraio}
  • D1 = {giorno: 1 D2 = {giorno : giorno = 29}
  • D3 = {giorno : giorno = 30}
  • D4 = {giorno : giorno = 31}
  • Y1 = {anno: anno = 1900}
  • Y2 = {anno: ((anno != 1900) AND (anno mod 4 = 0)}
  • Y3 = {anno: anno mod 4 != 0}

NextDate Test Cases con WECT

Esempio dei 4 test cases generati con strategia WECT.

Esempio dei 4 test cases generati con strategia WECT.


NextDate Test Cases con SECT

Esempio dei 36 test cases generati con strategia WECT.

Esempio dei 36 test cases generati con strategia WECT.


Testing dei valori limite (boundary values)

Il metodo delle classi di equivalenza partiziona il dominio di ingresso assumendo che il comportamento del programma su input della stessa classe è simile.

Poichè l’esperienza quotidiana ci insegna che tipicamente gli errori di programmazione capitano al limite tra classi diverse, il testing dei valori limite si focalizza su questo aspetto.

Estende la tecnica delle classi di Equivalenza, specificando quali valori scegliere.

Consideriamo una funzione foo(x1, x2)
Limiti:

a < = x1 < = b, c < = x2 < = d

Il metodo si focalizza sui limiti dello spazio di input per individuare i casi di test.

Verificare i valori della variabile di input al minimo, immediatamente sopra il minimo, un valore intermedio (nominale), immediatamente sotto il massimo e al massimo.

Convenzione: min, min+, nom, max-, max.

Mantenere tutti i valori delle variabili, eccetto una, al loro valore nominale, mentre l’altra assume i valori estremi.

Boundary Analysis Test Cases

Considerando il metodo foo specificato nella precendente, slide, l’area azzurra in figura ci mostra la classe di equivalenza di valori validi.

Test set ={<x1nom, x2min>, <x1nom, x2min+>, x1nom, x2nom>, >x1nom, <2max->, <x1nom, x2max>, <x1min, x2nom>,<x1min+,x2nom,>,<x1max-,x2nom>,<x1max, x2nom>}.

Una funzione con n variabili richiede 4n + 1 casi di test.
Funziona bene con variabili che rappresentano quantità fisiche discrete.
Cosa fare con booleani, stringhe, etc?

Limiti dell’approccio Boundary: Non considera la natura della funzione e il significato delle variabili.
Considera che le variabili siano indipendenti. Non testa mai combinazioni di valori!

Worst-Case testing per variabili non-independenti

Se le variabili di input non sono indipendenti, dobbiamo testare tutte le combinazioni di valori che queste variabili possono assumere.

Partendo dal Boundary testing, ognuno dei 5 valori che può assumere una varible deve essere interato per ognuno dei 5 valori delle altre variabili.

Di conseguenza, dati n parametri di una funzione, avremo 5n casi di test per classe di equivalenza valida.

Esempio di WCT per 2 variabili.

Esempio di WCT per 2 variabili.


White Box Testing

La definizione dei casi di test e dell’oracolo è fondata sulla base della conoscenza della struttura del software.

Si selezionano quei test che esercitano tutte le strutture del programma.

In base a cosa si intenda per “struttura” si avranno diverse sotto-strategie.

Non è scalabile (usato soprattutto a livello di unità o sottosistema).

Attività complementare al testing Black Box

Non può rilevare difetti che dipendono dalla mancata implementazione di alcune parti della specifica.

La definizione dei casi di test è fondata sull’adozione di criteri di copertura degli oggetti che compongono la struttura dei programmi.

COPERTURA: definizione di un insieme di casi di test in modo tale che gli oggetti di una definita classe (es. strutture di controllo, istruzioni, archi del GFC, predicati,..etc.) siano attivati almeno una volta nell’esecuzione dei casi di test

Definizione di una metrica di copertura:

Test Effectiveness Ratio (TER) = # oggetti coperti / # oggetti totale

Selezione di casi di test

Problema: come selezionare i casi di test per il criterio di copertura adottato?
Copertura dei Nodi

  • Dato un programma P, viene definito un insieme di test case la cui esecuzione implica l’attraversamento di tutti i nodi di GFC(P), ovvero l’esecuzione di tutte le istruzioni di P.
  • TER = n.ro di statement eseguiti / n.ro di statement totale.

Copertura delle decisioni

  • Dato un programma P, viene definito un insieme di test case la cui esecuzione implica l’attraversamento di tutti i rami di GFC(P), ovvero l’esecuzione di tutte le decisioni di P.
  • TER = n.ro di decisioni eseguite / n.ro di decisioni totali.

Selezione di casi di test (segue)

Copertura delle condizioni

  • Dato un programma P, viene definito un insieme di test case la cui esecuzione implica l’esecuzione di tutte le condizioni (valori vero e falso delle componenti relazionali dei predicati) caratterizzanti le decisioni in P.
  • TER = n.ro di condizioni booleane eseguite / n.ro di condizioni booleane totali.

Copertura dei cammini

  • Dato un programma P, viene definito un insieme di test case la cui esecuzione implica l’attraversamento di tutti i cammini di GFC(P).
  • TER = n.ro di cammini eseguiti / n.ro di cammini totali.

Node Coverage: Esempio

Copertura del 100%: cammino 1, 2, 3, 4, 5, 6, 7.

Per coprire tutti i nodi basta dare in input qualunque X != 0
input data per caso di test:

  • y: qualsiasi valore;
  • x: valore diverso da 0

NB: failure per x = 0

E’ un tipo di test che non garantisce di aver percorso tutte le “strade” (rami) almeno una volta
Un test che come prima esegue tutti i comandi, ma non tutti i rami
Altre soluzioni → Decision Coverage

Codice di Esempio.

Codice di Esempio.

Grafo del Flusso di Controllo corrispondente.

Grafo del Flusso di Controllo corrispondente.


Decision Coverage: Esempio

Cammini presenti nel Grafo da Ni a Nf:

a) 1, 2, 3, 4, 6, 7
b) 1, 2, 3, 5, 6, 7

Decisioni:

a) X == 0 || Y > 0
b) X != 0 && Y 0, x != 0
b) y

NB: failure per x = 0

Il problema si manifesta perché l’espressione booleana prevede più condizioni.
Altre soluzioni → Condition Coverage

Codice di Esempio.

Codice di Esempio.

Grafo del Flusso di Controllo corrispondente.

Grafo del Flusso di Controllo corrispondente.


Path Coverage: Esempio

Problema
I cicli possono portare a cammini infiniti (es.:1, 2, 3, 4, 5, 6, 7, 5, 6, 7, …).

Un numero di cammini infinito implica la presenza di circuiti.
NB: il numero dei cammini elementari (privi di circuiti) in un grafo è finito.
Soluzione: limitare l’insieme dei cammini.

Criterio di n-copertura dei cicli
Si seleziona un insieme di test case che garantisce l’esecuzione dei cammini contenenti un numero di iterazioni di ogni ciclo non superiore ad n (ogni ciclo deve essere eseguito da 0 ad n volte).
Al crescere di n può diventare molto costoso.
Caso pratico n = 2 (ogni ciclo viene eseguito 0 volte, 1 volta , 2 volte).
NB: il criterio di 1-copertura dei cicli (n = 1) implica il criterio di copertura dei branch.


  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion