Upload
giacomo-petronio
View
478
Download
0
Embed Size (px)
DESCRIPTION
Università di Trieste, corso di laurea in ingegneria informatica 2014: seminario Unit Testing
Citation preview
Unit Testing
30/04/2014 - Giacomo Petronio
Cronoprogramma
● Software testing e software checking● Livelli di test● Unit test / JUnit● Codice testabile● Dependency Inversion● Friendly Classes● Test-Driven Development
Software Testing
Venire a conoscenza di eventuali rischi
Verifica dei requisiti espliciti ed impliciti
Valutazione della Qualità● Correttezza
● Affidabilità
● Robustezza
● Usabilità
● Efficienza
● Manutenibilità
● Portabilità
Software Checking
Attività che mira a valutare un attributo o un comportamento di un sistema, ed a verificare che questo soddisfi i requisiti.
Checking is the process of making evaluations by applying algorithmic decision rules to specific observations of a product.
Test Correttezza
Black-boxBasati sulle specificheDiversi livelli
Test Correttezza
Livello Pro ControSystem tests
alta confidenza se tutto OK lenti
poco indicativi in caso di fail
difficilmente automatizzabili
Unit tests veloci
molto indicativi in caso di fail
automatizzabili
confidenza relativa
# tests
tempoesecuzione
Scenario
Integration Tests
Unit Tests
test intero sistemapunto di vista dell'utente
test di collezioni di classisottosistemi isolati
test di classi singole
Livelli di test
Struttura Unit Test
Test DriverUnit Under Test
Stimolo
Assert
Contesto
JUnit
JUnit Asserts
assertEquals(expected, actual)
assertTrue(value)assertFalse(value)
assertNull(value)assertNotNull(value)
assertThat(value, Matcher)● assertThat(value, is("A"));● assertThat(value, is(true));● assertThat(value, is(notNull()));
Running JUnit Tests
JUnit Best Practices
● N model classes → N test classes
● 1 test case per funzionalità
Stack Test Cases● test Empty Stack● test Correct Order● test Null Input● test Pop When Empty
JUnit Best Practices
Un assert per test caseStack stack = new Stack();stack.push("A");
assertFalse(stack.isEmpty());assertEquals("A", stack.peek());assertFalse(stack.isEmpty());assertEquals("A", stack.pop());assertTrue(stack.isEmpty());
JUnit Best Practices
White box / Black box
JUnit Best Practices
Come testo un metodo privato?
● non testare
● reflection
● cambiare visibilità
● classe emergente
JUnit Best Practices
Nome Classe di Test
Stack StackTest
Stesso package ma diversa cartella ● src/it/units/inginf
o Stack.java● test/it/units/inginf
o StackTest.java
stackShouldBeEmpty(){ … }popShouldReturnNullWhenEmpty(){ … }
peekShouldNotRemoveItem(){ … }
JUnit Best Practices
Nomi test-case verbosi
test01(){ … }test02(){ … }
JUnit Best Practices
Testare le eccezioni
@Test(expected=NullPointerException.class)public void shouldThrowExceptionOnNullInput() {
Stack stack = new Stack();stack.push(null);
}
JUnit Best Practices
Classi di equivalenza
Testare tutti gli input Risorse LimitateVS
IMPORTANTE!!Caratteristiche di ogni Unit Test
Velocità Ripetibilità Indipendenza
DBMSNetworkingFile-System
Benefici Unit Testing
12 3
Documentazione
Regression testing
Refactoring
Facile…
Test DriverUnit Under Test
Stimolo
Assert
Contesto
… o no?
Come scrivere codice non testabile
● Mescolare i new con la logica● Codice nel costruttore● Global state (es. singletons)● Metodi statici● Troppi condizionali● Troppe responsabilità
Test DriverUnit Under Test
Stimolo
Assert
Contesto
Other Class
Other Class
Other Class
DB
File System
Internet
Facile…?
Test DriverUnit Under Test
Stimolo
Assert
Contesto
Other Class
Other Class
Other Class
DB
File System
Internet
Codice Testabile
SEAM
Test DriverUnit Under Test
Stimolo
Assert
Contesto
Friendly
Friendly
Friendly
Codice Testabile
SEAM
Codice Testabile
Crezione Business LogicGrafo degli Oggetti
Test DriverUnit Under Test
Friendly
Friendly
Friendly
Codice Testabile
SEAMOggetto istanziato
Dependency Inversion SOLIDConcrete, Abstract
Concrete Abstract
class Geek { playWith(PlayStation ps){
ps.play(); }}
class Geek { playWith(IConsolle c){
c.play(); }}
Esempio
MovieFilter
+moviesDirectedBy(director)
<<Interface>>MovieFinder
+ getAllMovies()
MovieFinderImpl<<crea>>
esempio…
Inversion of Control (IoC)
MovieFilter
+moviesDirectedBy(director)
<<Interface>>MovieFinder
+ getAllMovies()
MovieFinderImpl<<crea>>
Assemblatore <<crea>>
<<inject>>
IoC: Dependency Injection
● Constructor Injectiono Dipendenze esplicite
● Setter Injectiono Dipendenze meno espliciteo Comodo in classi esistenti
● Frameworko Guiceo Springo CDI (J2EE)
IoC: Service Locator
MovieFilter
+moviesDirectedBy(director)
<<Interface>>MovieFinder
+ getAllMovies()
MovieFinderImpl
Service Locator
<<chiede>>
<<crea>>
Friendly Classes
Stub● Non hanno logica interna● Comportamento predefinito● Non si effettuano verifiche sugli stub● Es. finta risorsa web
Friendly Classes
MockProgrammabile:
● “Quando ricevi X…”o restituisci Yo lancia eccezioneo …
Verifiche sui mock:● Numero di chiamate● Controllo parametro passato
Mockito
Mock Lifecycle:● Crea mock a partire da interfaccia● Programma comportamento voluto● Utilizzo indiretto● Verifica dell’utilizzo
Mockito
Esempio
MovieFinder finder = mock(MovieFinder.class)
when(finder.findAll()).thenReturn(allMovies);
MovieFilter filter = new MovieFilter(finder);
Lister.moviesDirectedBy(“Martin Scorsese”);
verify(finder).findAll(); // verifica la chiamata
esempio…
Mockito
MovieFinder finder = mock(MovieFinder.class)when(finder.findAll()).___________ .thenReturn(allMovies); .thenReturn(none, all); .thenThrows(new RuntimeException()); .then( callback );
MovieLister lister = mock(MovieLister.class)when(lister.moviesDirectedBy(_____)).then(…); “Martin Scorsese” anyString() any()
Legacy Code
“Codice ereditato da altri?”“Codice rimasto da una versione precedente?”
Codice senza test
Test Driven Development
Si sviluppa in 3 fasi:RED scrivere un singolo test che fallisceGREEN scrivere quanto basta per far passare i testBLUE refactoring
Metodologia di sviluppo
Test Driven Development
Test First
Effetti diretti sul codice:● Disaccoppiato● Coeso● Testabile● API Driven