vuoi
o PayPal
tutte le volte che vuoi
Definizioni nel Testing e Debugging del Software
Il Testing è un processo di esecuzione del SW allo scopo di rilevare i failure, mentre il Debugging è un processo che parte dal failure (cioè dall'output del Testing), ed ha come scopo di risalire al fault che ha generato quel failure.
Un Test case è un caso di prova del test, cioè l'insieme di input e condizioni di esecuzione con il quale eseguiamo un singolo test. Invece la Test Suite è l'insieme dei casi di test, per essere buono deve avere al suo interno almeno un test case che riesce a rilevare un failure del sistema. Nei test case devo specificare anche l'Oracolo, cioè la descrizione del comportamento atteso del programma, perché devo osservare se il comportamento osservato coincide con quello atteso.
Dijkstra nella sua tesi di laurea dimostrò matematicamente che il Testing non può mai dimostrare l'assenza di difetti, ma solo la loro presenza, qualsiasi sia la
Tecnica che useremo. Perciò non posso certificare il SW se non ho una tecnica di Testing che dimostri la totale assenza di difetti, posso solo fornire un'indicazione sulla sua affidabilità e qualità.
Un test case ha successo se il sistema fallisce, perché altrimenti è inutile; se vado a risolvere solo errori facilmente correggibili; può comportare l'inadeguatezza dei miei testcase, cioè che non sono in grado di rilevare certi failure.
Vi sono tre approcci generali al testing:
- Black Box Testing: si effettuano dei test per dimostrare che ciascuna funzione è completamente operativa, vedendo il sistema come una scatola nera, basandosi solo sulla conoscenza della specifica funzionale, ignorando la struttura interna del SW (conosco solo l'interfaccia dei metodi, non la loro implementazione). I test, in queste tecniche sono condotti sulle interfacce SW per verificare che i dati in input siano accettati in maniera appropriata.
I dati in output siano corretti e sia mantenuta l'integrità delle informazioni esterne.
White Box Testing: si effettuano dei test per verificare che le operazioni interne siano svolte correttamente conoscendo il funzionamento interno, cioè come funzionano i vari componenti e come sono implementati, infatti vengono esaminati i dettagli del codice, viene svolto un test dei cammini logici interni però in generale è impossibile eseguire un testing esaustivo di tutti i cammini.
Grey Box Testing: è una sorta di Black Box Testing dove si va a guardare anche il codice.
Le aziende, in genere utilizzano la seguente strategia di Testing:
- Si parte in genere dai Test di Unità nei quali vengono testati i singoli moduli, per poi passare al Test d'Integrazione in cui si mettono insieme i vari moduli e si testa il comportamento di parte o di tutto il sistema;
- Poi seguono i Test di Validazione e di Sistema.
Si procede ora a vedere più
nellospecifico le caratteristiche dei vari test:- Test di Unità: È una tecnica White Box che effettua una verifica della più piccola unità di progettazione SW, che è il modulo (che può essere ad esempio una classe). Si testa il modulo usando delle check list costruite dallo sviluppatore sulla base dell'esperienza acquisita e imposte dall'azienda, tale processo è relativamente automatizzato. Esempio di strumento per eseguire il Test di Unità è JUnit. Il problema è che il modulo non si può testare da solo, in quanto spesso esso è legato ad altri moduli, quindi è necessario sostituire i moduli reali con dei moduli fake detti stub, i quali ci permettono di individuare solo i faults relativi all'unità isolata, perché se l'analizzassimo insieme alle altre unità a cui è legata non riusciremmo a individuare i faults dovuti a quella singola unità.
inquanto verrebbero fuori anche i faults relativi alle altre unità a cui esso è legata. Occorreanche creare un modulo driver, cioè una sorta di main che richiama la classe da testare.Driver e stub sono onerosi in quanto devono essere realizzati ma non fanno parte delprodotto finale. Spesso accade che il codice da testare costa meno degli stub che devocostruire per testarlo. Il Testing di unità più facile con moduli ad alta coesione e bassolivello di disaccoppiamento perché in questo caso ho che i moduli interagiscono il menopossibile, ho un minor numero di test-case, errori rilevabili più facilmente, devoimplementare meno stub.
Test d’integrazione: dopo aver risolto i faults di ogni modulo con il Test di Unità, occorretestare l’interazione tra i vari componenti per capire cosa succede quando integriamoinsieme più moduli. Esistono due approcci: Top-Down nel quale si parte dal Main e siintegrano i moduli di
primo livello seguendo la gerarchia e creando gli stub (che dovremmo avere a disposizione dai Test di Unità) per simulare i moduli di secondo livello, l’altro approccio è il Bottom-Up nel quale si parte dall’integrare i moduli del livello più basso per poi risalire tutta la gerarchia; il PRO è che si elimina la necessità degli stub, mentre il CONTRO è che è più difficile creare il caso di test in quanto diventa più complicato capire qual è la funzionalità di alto livello da testare.
Test di validazione/accettazione: detto anche Alpha test per la Microsoft o FAT, è fatto in azienda su un prototipo realistico, a tale Test è presente oltre allo sviluppatore anche il committente.
Test di sistema: detto anche Beta test per la Microsoft o SAT consiste nel far girare il prodotto finale sul sistema reale è quello che spesso viene chiamato collaudo. Oltre al committente è presente
anche il cliente, ma non sempre lo sviluppatore.Dato che la fase di Testing dovrebbe coprire tutte le fasi del ciclo di vita del SW, si generalizza il classico modello a cascata con quello che prende il nome di modello V&V:
Ciascuna delle fasi del ciclo di vita del SW prevede una fase di Testing dedicata, e man mano che ogni fase viene realizzata occorre definire i test case che saranno usati nel Test di Regressione: il test inizia dai bisogni del cliente cioè dai requisiti informali che dovranno essere tradotti in un documento di specifica, e già in questa fase occorre iniziare a preparare i test di accettazione e di sistema (è il test che in genere si deve mettere nella gara d’appalto per convincere il cliente). Nella fase di progettazione occorre invece preparare i Test Case da usare nel Test di Integrazione, mentre durante la fase di sviluppo occorre definire i Test Case da usare nei Test di Unità. Dopodiché è possibile iniziare la fase
di Test, applicando i Test Case definiti in precedenza. Grazie alla ricorsione del modello, se viene rilevato un Fault dal Test di Integrazione, è necessario andare a riaggiustare la progettazione e lo sviluppo e ripartire daccapo dal Test di Unità: questa ricorsione a V prende il nome di Test di Regressione, poiché ogni volta che viene apportata una modifica al ramo di sinistra occorre ripetere tutti i Test definiti nel ramo di destra. Ci aiutano in questa ripetizione ricorsiva dei Test strumenti automatizzati come JUnit.
Vediamo alcune problematiche legate al Testing:
- Quando inizia il testing? I test vanno pianificati in anticipo, il Testing inizia nella fase di stesura della proposta durante la gara d'appalto.
- Quando finisce il testing? Solo quando il SW viene dismesso. Ovviamente il SW rilasciato non sarà privo di fault, e quindi si decide di terminare l'attività di Testing quando si è raggiunto un grado di Dependability specificato.
Dal contratto, altri criteri di copertura possono essere il numero di stati coperti, o criteri economici/temporali ad esempio quando finiscono i soldi e il tempo previsti per quel progetto. Nel contratto sono indicati le penali da pagare in caso di failure calcolate sulla base dei danni provocati e sul tempo di ripristino.
Come selezioniamo i casi di Test da fare? Occorre fare un'ottimizzazione in modo che se ne facciano nel minor numero possibile, limitandoci a quelli che hanno successo, cioè che fanno fallire il sistema. Un criterio generale è il partizionamento, cioè individuiamo delle classi di equivalenza (insieme di stati), ciascuna delle quali deve essere coperta con un testcase.
Le tecniche di Testing si dividono in due grandi famiglie:
- Tecniche di Testing Funzionale: è una famiglia di tecniche di tipo Black Box e mira a testare le funzionalità del componente SW verificandone il soddisfacimento dei requisiti descritti nel documento di specifica.