Riassunto Reti PDF
Document Details
Uploaded by Deleted User
Tags
Summary
Questo documento fornisce un riassunto di argomenti di testing del software, inclusi concetti di base come la terminologia del testing, strategie di testing (funzionale e strutturale), l'automazione tramite JUnit e altri aspetti tecnici del testing software. Il documento sembra essere un insieme di appunti o un manuale di formazione.
Full Transcript
Giorno 1: Introduzione al Testing e Terminologia di Base Il testing del software è un processo che include attività di pianificazione, preparazione e valutazione dei prodotti software per verificarne la conformità ai requisiti, l'idoneità allo scopo e l'individuazione di difett...
Giorno 1: Introduzione al Testing e Terminologia di Base Il testing del software è un processo che include attività di pianificazione, preparazione e valutazione dei prodotti software per verificarne la conformità ai requisiti, l'idoneità allo scopo e l'individuazione di difetti. È fondamentale comprendere la terminologia specifica del testing per evitare confusione. Un errore è una svista commessa da una persona, ad esempio durante la scrittura del codice, che porta ad un bug. Un bug (o difetto o fault) è il risultato di un errore. Un fallimento si verifica quando il codice contenente un bug viene eseguito. Un incidente è un sintomo che indica un fallimento e richiede un'indagine. Un test è l'azione di esercitare un sistema software con uno o più casi di test. L'obiettivo è quello di "rompere" il sistema o dimostrarne la corretta esecuzione. Un caso di test è un prodotto di lavoro riconosciuto, associato a un comportamento del sistema, con input e output attesi. Una descrizione completa di un caso di test include un identificatore, una descrizione, precondizioni, input, output attesi, postcondizioni e la cronologia di esecuzione [5, 6]. Una test suite è un insieme di casi di test. Le fonti di bug possono essere introdotte nelle fasi di sviluppo e durante la risoluzione di un fault. Giorno 2: Strategie di Testing e Livelli di Test Esistono due principali strategie per identificare i casi di test: Testing funzionale (o basato sulla specifica o black-box testing): il sistema è considerato una "scatola nera" e i test derivano dai requisiti [7-9]. Testing strutturale (o basato sul codice o white-box testing): l'implementazione è nota e utilizzata per identificare i casi di test [8, 10]. Non esiste un approccio sufficiente di per sé; è necessaria una combinazione dei due approcci. I livelli di test includono: unit test, integration test, system test e acceptance test. Essi riflettono le fasi del modello a cascata. Il test delle unità verifica singolarmente le parti minime di un sistema (unità). In un sistema procedurale, un'unità può essere una procedura, una funzione, ecc., mentre in un sistema orientato agli oggetti, può essere una classe o un metodo [12, 13]. Giorno 3: Automazione dei Test e JUnit L'esecuzione dei test dovrebbe essere automatica. L'automazione riduce i costi, gli errori umani e supporta il regression testing [13, 14]. JUnit è un framework per l'automazione dei test, in particolare per l'unit testing. Esistono framework simili (xUnit) per altri linguaggi [14, 15]. Un'asserzione (assertion) verifica un singolo risultato atteso. Esistono diversi tipi di asserzioni, come assertTrue, assertEquals, ecc.. Un metodo di test verifica un singolo comportamento del sistema e corrisponde a un caso di test. È annotato con @Test e contiene almeno un'asserzione [17, 18]. Una classe di test contiene tutti i metodi di test per una data classe [15, 19]. Maven è uno strumento per l'automazione della build che aiuta a creare un'applicazione eseguibile dal codice sorgente. L'annotazione @BeforeEach permette di inizializzare una nuova istanza della classe di test prima di ogni test, evitando problemi di dipendenza tra i test [20, 21]. Giorno 4: Specification-Based Testing e Test Parameterizzati Il specification-based testing (o functional testing) è guidato dai requisiti del software. Si parte dall'analisi dei requisiti e si derivano i test. Un test deve verificare cosa il software deve fare o non fare, quali sono gli input e output, i tipi di variabili coinvolte e i domini di input [22-24]. Il testing funzionale include l'identificazione delle partizioni di input e output, dei casi limite e di combinazioni di input [22, 25, 26]. I casi limite (o corner cases) sono punti in cui i bug sono più probabili e devono essere verificati [27-29]. I test parameterizzati consentono di eseguire lo stesso test più volte con diversi argomenti [30, 31]. Giorno 5: Structural Testing, Code Coverage e Altre Tecniche Il structural testing (o code-based testing) utilizza la struttura del codice per creare test. Il code coverage è una metrica che indica quanto codice è stato esercitato dai test [10, 33, 34]. I code coverage tool sono usati per identificare parti di codice non coperte dai test [34, 35]. I criteri di coverage includono: line coverage, branch coverage, condition coverage e MC/DC coverage [36-38]. Il mutation testing è un approccio per valutare la qualità dei test, introducendo mutazioni nel codice e verificando se i test rilevano tali modifiche [39, 40]. Il design by contract consiste nel definire precondizioni, postcondizioni e invarianti per i metodi e le classi, al fine di garantire la corretta interazione tra gli oggetti [41-43]. Il property-based testing (PBT) si basa sulla definizione di proprietà che il programma deve soddisfare, lasciando al framework di test la generazione di input casuali [44-46]. I test doubles (stub, fake, mock) sono oggetti che sostituiscono le dipendenze reali durante i test. Sono utili per semplificare i test e isolare le unità. Il static testing (o software review) include revisioni del codice fatte da persone, senza l'esecuzione del codice [49, 50]. I system test coprono l'intera interazione dell'utente con il sistema per raggiungere un obiettivo [51, 52]. I Page Objects (POs) sono modelli che rappresentano le pagine web e le loro interazioni. Gli integration test verificano l'interazione tra componenti del sistema, come DAO e database [54, 55]. Il Test-Driven Development (TDD) prevede la scrittura di un test prima della scrittura del codice di produzione [56, 57]. Il ciclo TDD include scrivere un test, farlo fallire, scrivere il codice per farlo passare e poi rifattorizzare. La qualità del codice di test è fondamentale. I test devono essere veloci, coesivi, indipendenti, ripetibili, facili da scrivere e leggere e devono avere una singola ragione di fallimento [58-63]. È importante evitare i test smell che possono compromettere la qualità della test suite [63-66].