[Sommerville] Verification and Validation (V&V)
‘checking processes which ensure that software conforms to its specification (at each phase in the development) and meets the needs of the software customer’.
[Boehm'79]
Verification: “Have we built the product right”?
Validation: ” Have we built the right product”
La fase di verifica & validazione serve ad accertare che il software rispetti i requisiti e che li rispetti nella maniera dovuta.
Verifica: il software rispetta le specifiche?
E’ stato implementato tutto quello descritto nel documento dei requisiti?
Ho implementato correttamente tutte le funzionalità?
Da sola non basta.
Validazione (o convalida): il software rispetta ciò che voleva il cliente?
In altri termini: i requisiti modellano ciò che il cliente realmente voleva?
Questa fase è molto delicata in quanto, dopo tutto il processo si può ottenere un software perfettamente funzionante, senza errori, ma del tutto inutile in quanto non rispecchia quanto era stato chiesto all’inizio.
La verifica può essere statica, se effettuata su carta, o dinamica, se effettuata attraverso l’esecuzione del software.
Affidabilità: La misura di successo con cui il comportamento osservato di un sistema è conforme ad una certa specifica del relativo comportamento.
Fallimento (failure): Qualsiasi deviazione del comportamento osservato dal comportamento specificato.
Stato di Errore (Errore): Il sistema è in uno stato tale che ogni ulteriore elaborazione da parte del sistema porta ad un fallimento.
Difetto (Bug/fault): La causa meccanica o algoritmica di un errore .
Ci sono molti tipi differenti di errori e molti modi per far fronte ad un errore.
Nel codice mostrato a destra, che secondo i requisiti dovrebbe calcolare il doppio di un numero preso in input, per il valore di ingresso x = 3 si ha il valore di uscita y = 9.
La causa di questa failure è il fault di linea 2, in cui anziché l’operatore + è usato l’operatore *
NB: Se il valore di ingresso è x = 2, il valore di uscita è y = 4 (nessuna failure).
Nota:
Usiamo il termine Defect (difetto) quando non è importante distinguere fra fault e failure, per riferirsi sia alla causa (fault) che all’effetto (failure).
Esempio di codice con un fault, che genera un failure.
Si dice che un programma è “stressato” da un caso di test (insieme di dati di input), o “test case“.
Un test è formato da un insieme di test cases.
L’esecuzione del test consiste nell’esecuzione del programma per tutti i casi di test.
Un test ha successo se rileva uno o più malfunzionamenti del programma.
Condizione necessaria per effettuare un test: conoscere il comportamento atteso per poterlo confrontare con quello osservato.
L’Oracolo è la definizione del comportamento atteso per ogni caso di prova.
Oracolo umano: si basa sulle specifiche o sul giudizio.
Oracolo automatico:
Il test di applicazioni grandi e complesse può richiedere milioni di casi di test.
La dimensione dello spazio di uscita può eccedere le capacità umane.
L’occhio umano è lento e poco affidabile anche per uscite di piccole dimensioni → Necessità di avere oracoli automatici.
L'esempio mostra come non sia possibile effettuare test esaustivo, ma siano necessarie strategie più raffinate.
Le tecniche di verifica possono essere divise in due macro-categorie:
La Verifica Statica è basata su tecniche di analisi statica del software senza ricorso alla esecuzione del codice.
Analisi statica: è un processo di valutazione di un sistema o di un suo componente basato sulla sua forma, struttura, contenuto, documentazione
Tecniche: review, ispezione, verifica formale, esecuzione simbolica, etc…
Reviews: ispezione manuale del codice sorgente
Due tipi di review:
Le Ispezioni mirano a trovare fault in una componente rivedendo il codice sorgente in meeting formali.
E’ condotta da un team di sviluppatori, incluso l’autore della componente, un moderatore e uno o più revisori che trovano i bug nella componente.
Anomalie del codice possono influenzare in modo scorretto il codice.
Esempi: distribuzione linee bianche, numero linee di commento,…
Tecniche di ispezione di codice possono rilevare ed eliminare anomalie fastidiose e rendere più precisi i risultati una tecnica completamente manuale per trovare e correggere errori, poco tecnologica, ma efficace, ma sono possibili alcuni supporti automatici …
E’ estendibile a progetto, requisiti, … seguendo principi organizzativi analoghi
Attori coinvolti:
Moderatore: tipicamente proviene da un altro progetto. Presiede le sedute, scegli i partecipanti, controlla il processo.
Lettori, addetti al test: leggono il codice al gruppo, cercano difetti
Autore: partecipante passivo; risponde a domande quando richiesto
Fagan ha proposto un processo per effettuare le Inspection, basato sui seguenti passi:
Obiettivo: trovare il maggior numero possibile di difetti:
Approccio: parafrasare il codice linea per linea:
Necessario restare in tema:
Circa 2.5 pagine per codice C , 4 per FORTRAN diviso in: funzionalità, uso dei dati, controllo, connessioni, calcolo, manutenzione, chiarezza
Esempi:
Sintassi:
Struttura:
Stile:
Il metodi di ispezione sono molto efficaci: Circa 85% dei fault può essere individuato.
L’evidenza dice che è cost-effective, perchè?
Limiti
E’ fondata sull’esecuzione del codice.
Analisi dinamica: il processo di valutazione di un sistema software o di un suo componente basato sulla osservazione del suo comportamento in esecuzione
Testing: Approccio strutturato alla selezione di casi di test e dati associati.
Debugging: non c’è uniformità in letteratura.
In generale, riguarda l’individuazione e l’eliminazione dei difetti.
Debugging implica formulare ipotesi osservando il comportamento del programma e quindi verificare queste ipotesi per localizzare gli errori.
Il Testing consiste nel trovare le differenze tra il comportamento atteso, specificato attraverso il modello del sistema e il comportamento osservato dal sistema implementato.
Obiettivo: progettare test per provare il sistema e rivelare problemi.
Massimizzare il numero di errori scoperti che consentirà agli sviluppatori di correggerli.
Questa attività va in contrasto con le altre attività svolte prima: analisi, design, implementazione sono attività “costruttive”. Il testing invece tenta di “rompere” il sistema.
Il testing dovrebbe essere realizzato da persone che non sono state coinvolte nelle attività di sviluppo del sistema.
Il testing avviene a vari livelli.
Unit testing
Trovare differenze tra object design model e corrispondente componente
Structural (integration) testing
Trovare differenze tra system design model e un sottoinsieme integrato di sottosistemi
Functional testing
Trovare differenze tra use case model e il sistema
System testing
Trovare differenze tra requisiti non funzionali e il sistema
Le relazioni tra modelli e livelli di testing sono meglio esplicitate nel cosiddetto Modello a V.
Nella prossima lezione sarà dettagliato come effettuare i test.
1. Introduzione all'Ingegneria del Software – La qualità del Software
2. Il Ciclo di vita del Software: i modelli di Processo
3. Concetti e strumenti di base per il Project Management
5. Introduzione ad UML: Gli Use Case Diagrams
6. Il documento dei Requisiti Software
7. UML: I Sequence Diagrams ed i Class Diagrams