Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Schema:
- Quali sono gli obiettivi della verifica?
- Quali sono i principali approcci alla verifica?
o Che tipo di garanzia otteniamo attraverso i test?
o Come si possono fare sistematicamente i test?
o Come possiamo rimuovere i difetti (debug)?
• Quali sono i principali approcci all'analisi del software?
Informali vs. formali.
Verifica in Ingegneria:
Esempio del Design Bridge. Un test può assicurare infinite situazioni corrette.
Commento: Se ommettiamo questo, la routine funziona se l’altro non viene mai toccato. (cioè se la
dimensione della tabella è una potenza del 2).
Definizione 1:
P => Programma; D => Dominio di input; R => Dominio di output
Quindi: P: D -> R (Potrebbe essere parziale)
Definizione 3:
• Test caso t:
- Un elemento di D.
• Test set T:
- un sottoinsieme finito di D.
• Il test ha esito positivo se P(t) è corretto.
• Test eseguito con successo se P è corretto per tutte le t in T.
Definizione 4:
• Test set ideale T:
- Se P è errato, esiste un elemento di T tale che P(d) è errato.
• Se esistesse un test set ideale per qualsiasi programma, potremmo provare la correttezza del
programma testandolo.
Criterio di test:
• Un criterio C definisce un sottoinsieme finiti di D (test set):
- C ⊆ 2^D
• Un test set T soddisfa C se è un elemento di C:
• Esempio:
Test in piccolo:
Testiamo singoli moduli:
• Test BLACK BOX (funzionali) - criteri di partizionamento basati sulle specifiche del modulo. Test di
ciò che il programma dovrebbe fare.
• Test WHITE BOX (strutturali) - criteri di partizionamento basati sul codice interno del modulo. Test
di cosa fa il programma.
Debolezza (Weakness):
{<x = 0, z = 1>, <x = 1, z = 3>} provoca l'esecuzione di tutti i bordi, ma non espone a zero
il rischio di una divisione.
Il problema di fattibilità:
I comportamenti sintatticamente indicati (istruzioni, bordi, ecc.) Sono spesso impossibili:
- codice irraggiungibile, bordi non realizzabili, percorsi, ecc.
• I criteri di adeguatezza possono essere impossibili da soddisfare:
- Giustificazione manuale per omettere ogni test case impossibile.
- "Punteggi" adeguati basati sulla copertura:
o esempio: copertura dell'istruzione del 95%.
Ulteriore problema:
Cosa succede se il codice omette l'implementazione di alcune parti delle specifiche?
I casi di white box test derivati dal codice ignoreranno quella parte delle specifiche!
Ulteriori vincoli:
"Sia B che I escludono P (cioè: non si può chiedere sia il
testo normale che il testo in corsivo per la stessa porzione
di testo.) E e SE si escludono a vicenda."
Criterio di Copertura:
• Generare tutte le possibili combinazioni di input e verifica l’output.
• Può ridurre il numero andando indietro negli output
- Nodo OR con output vero:
▪ utilizzare combinazioni di input, con un solo input vero.
- Nodo AND con output falso:
▪ utilizzare combinazioni di input con un solo input falso.
Criterio:
Dopo aver partizionato il dominio di input D in diverse classi, bisogna testare il programma utilizzando i
valori di input non solo "all'interno" delle classi, ma anche ai loro limiti. Questo vale per entrambe le
tecniche di: white box e black box.
Il problema dell’oracolo:
Come ispezionare i risultati delle esecuzioni dei test per rilevare guasti:
• Gli oracoli sono richiesti in ogni fase del test.
• Gli oracoli di test automatizzati sono necessari per l'esecuzione di grandi quantità di test.
• Gli oracoli sono difficili da progettare, nessuna ricetta universale.
Testing in generale:
• Test del modulo
- Test di un singolo modulo
• Test d'integrazione
- Integrazione di moduli e sottosistemi
• Test di sistema
- Testare l'intero sistema
• Test di accettazione
- Eseguito dal cliente
Test d'integrazione:
• Approccio big bang
Prima prova singoli moduli in isolamento.
- Quindi testare il sistema integrato.
• Approccio incrementale
- I moduli vengono progressivamente integrati e testati
Può procedere sia dall'alto verso il basso che dal basso verso l'alto secondo la relazione USES.
Se il processo di integrazione e test dal basso verso l'alto richiede solo driver.
Altrimenti, se procediamo dall'alto in basso sono necessari solo stubs.
Ereditarietà:
Data una gerarchia di classi, come testare le classi della gerarchia?
• "Appiattire" l'intera gerarchia e considerare ogni classe come un componente totalmente
indipendente, quindi non sfrutta l’incrementalità.
• Trovare un modo ad hoc per sfruttare la gerarchia.
Una strategia d’esempio:
• Un test che non deve essere ripetuto per nessun erede.
• Un test che deve essere eseguito per l'erede di classe X e tutti i suoi ulteriori eredi.
• Un test che deve essere ripetuto applicando gli stessi dati di input, ma verificando che l'output non
sia (o sia) modificato.
• Un test che deve essere modificato aggiungendo altri parametri di input e verificando che l'output
cambi di conseguenza.
Analisi:
Analisi vs. Testing:
• Il test caratterizza una singola esecuzione.
• L'analisi caratterizza una classe di esecuzioni; si basa su un modello.
• Hanno vantaggi e svantaggi complementari.
Prova di correttezza:
• Correttezza parziale:
- La validità di {Pre} Program {Post} garantisce che se il Pre è valido prima dell'esecuzione del
Program e se il programma terminerà, Post-condizione sarà raggiunto.
• Correttezza totale:
– Pre garantisce la chiusura dei programmi e la verità su Post.
Questi problemi non si possono descrivere.
Esempio (2):
Quando il controllo raggiunge la condizione, i valori simbolici non consentono all'esecuzione di selezionare
un ramo. Si può scegliere un ramo e registrare la scelta in una condizione di percorso.
Risultato:
<{a = A, y = Y + 5, x = 2 * Y + A + 7},
Esecuzione del percorso: <1, 3, 4>, Condizione del percorso: Y + 2 ≤ A>
• Read(x) => rimuove qualsiasi associazione esistente per x e aggiunge l'associazione x = X, dove X è
un valore simbolico appena introdotto.
• Write(expression) => output (n) = valore_simbolico_calcolato (contatore n inizializzato su 1 e
incrementato automaticamente dopo ogni istruzione di output).
• x := expression => costruire il valore simbolico di espressione, SV; sostituisce l'associazione
precedente per x con x = SV.
• Dopo l'esecuzione dell'ultima istruzione di una sequenza che corrisponde a un bordo del grafico di
controllo, aggiungere il bordo al percorso di esecuzione.
• If cond then S1; else S2; end if
• While cond loop … end loop => la condizione viene valutata simbolicamente
▪ Eval (cond)
o If eval (cond) => vero o falso quindi l'esecuzione procede seguendo il ramo appropriato.
o in caso contrario, fare una scelta non deterministica di vero o falso e congiungere
eval(cond) (oppure, not eval (cond)) alla condizione del percorso.
Ipotesi:
• Semplificazione dell’ipotesi: non più di un token in un luogo.
• Una sequenza di passi atomici può essere modellata da una sequenza d’attivazione.
– Questo risolve il non determinismo dovuto all'abilitazione di diverse transizioni.
• < valore_variabile_simbolica, esecuzione_percorso, condizione_di_percorso > può essere utilizzato
per modellare lo stato simbolico dell'interprete (esecuzione_percorso è la sequenza di attivazione).
Proprietà e prove:
Proprietà da verificare, fornita tramite una formula (nella logica temporale).
Nell'esempio, si può provare:
• È sempre presente un calcolo che consente al processo di sinistra di accedere alla regione critica.
• Non esiste alcuna garanzia che il processo di sinistra acceda alla risorsa condivisa a meno che non la
possieda già.
Perché così tanti approcci ai test e alle analisi?
• Test vs. analisi (correttezza).
• Tecniche formali contro informali.
• Tecniche white box contro black box.
• Tecniche nel piccolo / grande.
• Tecniche completamente automatiche vs. semiautomatiche (per proprietà indecidibili).
• ecc.
Visualizza tutti questi come complementari.
Debugging:
• è un’attività di localizzazione e correzione degli errori.
• Può iniziare dopo che è stato rilevato un errore.
• L'obiettivo è colmare il divario tra un errore e un fallimento:
- Memory dump (è un processo in cui i contenuti della memoria vengono archiviati e
visualizzati in caso di crash dell’applicazione o del sistema), Punti di controllo o watchpoint
(che sono dei breakpoint speciali che interrompono l'esecuzione di un'applicazione ogni
volta che cambia il valore di una determinata espressione, senza specificare dove potrebbe
verificarsi. A differenza dei punti di interruzione (che sono specifici della linea), i punti di
controllo sono associati ai file.
- Aiuto tramite asserzioni intermedie.
Verifica di altre qualità:
Prestazioni:
• Peggior analisi dei casi:
o Focus dimostra che il tempo di risposta del sistema è limitato da alcune funzioni delle
richieste esterne, rispetto al comportamento medio.
• Deviazione standard.
• Approcci analitici vs. sperimentali.
Affidabilità:
• Esistono approcci per misurare l'affidabilità su base probabilistica, come in altri campi
dell'ingegneria.
• Sfortunatamente ci sono alcune difficoltà con questo approccio.
• L'indipendenza dai guasti non vale per il software.
• L'affidabilità riguarda la misurazione della probabilità del verificarsi di un guasto.
• I parametri significativi includono:
– numero totale medio di guasti osservati al momento t: AF (t)
– intensità di guasto: FI (t) = AF' (t)
– tempo medio di guasto al tempo t: MTTF (t) = 1/FI(t)
• Il tempo nel modello può essere tempo di esecuzione d’orologio o di calendario.
Modello logaritmico:
Presuppone, in modo più prudente, che il decremento per guasto di FI diminuisce esponenzialmente:
FI (AF) = 𝐹𝐼0 exp (- 𝜃 AF)
𝜃: parametro di decadimento dell'intensità di guasto.
Obiettivo-domanda-metrica (GQM):
Premesse:
o Le metriche del software devono essere utilizzate per analizzare le qualità del software, non per
valutare le persone.
o La valutazione della qualità deve essere relativa al prodotto finale, ai prodotti intermedi e al
processo.
o Le metriche devono essere definite nel contesto di un paradigma di miglioramento della qualità
(QIP) completo e ben progettato.
GQM:
• Non riguarda la misurazione di una singola quantità o gruppo di quantità: ad es. Complessità
ciclomatica (Misura direttamente il numero di cammini linearmente indipendenti attraverso il grafo
di controllo di flusso).
• Un metodo che ha lo scopo di condurre da una definizione precisa degli obiettivi di misurazione
delle qualità (gli obiettivi) alle quantità (le metriche) le cui misure sono utilizzate per verificare il
raggiungimento di tali qualità.
Il metodo:
• Definisci l'obiettivo con precisione: esempio:
– Analizzare il sistema informativo allo scopo di stimare i costi dal punto di vista del gestore
nel contesto di una grande software house.
• Definire una serie adeguata di domande rivolte al raggiungimento dell'obiettivo dichiarato.
• Associare una metrica precisa a ogni domanda.