3. Fixture
● Scrivere i test è divertente, ma può diventare anche
ripetitivo
– La ripetitività crea brutto codice, difficile da mantenere
● Una delle maggiori fonti di duplicazione del codice sono
le inizializzazioni degli oggetti
● JUnit mette a disposizione il meccanismo delle fixture
● Una fixture è un insieme di dati o risorse comuni,
necessarie in più test
4. setUp e tearDown
● Sono metodi di TestCase e vengono chiamati
rispettivamente prima e dopo ogni testXXX()
● Luogo ideale per creare oggetti, aprire e chiudere
connessioni al database, eccetera
● Riducono le LOC dei test
● Il codice delle fixture è condiviso quindi tra tutti i test
del TestCase
– Se alcuni non ne necessitano, forse è meglio mettere il
relativo codice comune in dei semplici utility method
6. Eseguire la fixture una volta sola
● In alcuni casi, può essere utile eseguire la fixture una
volta sola per tutta la suite
● Anziché ricorrere a degli ineleganti flag, si usa il pattern
Decorator (o Wrapper), tramite la classe TestSetup
7. TestSetup
public class DbTest extends TestCase{
public static Test suite(){
TestSuite suite = new TestSuite(DbTest.class);
TestSetup wrap = new TestSetup(suite){
public void setUp() throws Exception{
}
public void tearDown() throws Exception{
}
};
return wrap;
}
public void testXXX(){ ...}
}
10. Cambio package
● Le classi principali stanno ora in org.junit.* anziché in
junit.framework.*
JUnit 3.8.1:
package com.mycompany;
import junit.framework.*;
...
11. Cambio package
● Le classi principali stanno ora in org.junit.* anziché in
junit.framework.*
JUnit 4.x:
package com.mycompany;
import org.junit.*;
...
12. Meno dipendenze
● Le classi di Test sono ora POJO e non ereditano più da
TestCase
– Una classe è di test se c'è almeno un metodo annotato
come @Test
JUnit 3.8.1:
import junit.framework.TestCase;
public class CalculatorTest extends TestCase{
...
}
13. Meno dipendenze
● Le classi di Test sono ora POJO e non ereditano più da
TestCase
– Una classe è di test se c'è almeno un metodo annotato
come @Test
JUnit 4.x:
public class CalculatorTest {
...
@Test
public void ....
}
14. Più espressività
● I metodi di test non devono più obbligatoriamente avere
la forma testXXX()
– Viene eseguito dal framework ogni metodo annotato come
@Test
JUnit 3.8.1:
...
public void testMetodoUno(){...}
public void nonMiEsegue(){...}
public void testMetodoDue(){...}
...
15. Più espressività
● I metodi di test non devono più obbligatoriamente avere
la forma testXXX()
– Viene eseguito dal framework ogni metodo annotato come
@Test
– Devono comunque restare void e senza parametri
JUnit 4.x:
@Test public void miEsegue(){...}
@Test public void esegueAncheMe(){...}
public void nonMiEsegue(){...}
...
16. Ancora più espressività
● Anche i metodi setUp() e tearDown() sono sostituibili
con metodi annotati
public void setUp() --------> @Before
public void tearDown() --------> @After
Esempio:
@Before
public void initResources(){...}
17. Problema
● Se le classi di test non ereditano più da TestCase, come
invocare le asserzioni?
Soluzione:
Grazie agli import statici di Java 5, rimane tutto come prima!
import static org.junit.Assert.*;
...
@Test
public void myTestMethod(){
...
assertEquals(obj1,obj2); In realtà, sta chiamando
} Assert.assertEquals !
18. Sempre sulle asserzioni...
● È più semplice verificare la presenza di eccezioni
JUnit 3.8.1:
try{
metodoCheSollevaUnaException();
fail();
}catch (Exception ex){ assertTrue(True) }
JUnit 4.x:
@Test(expected: Exception.class)
public void verificaEccezione(){ ...}
19. No suite
● JUnit 4.x non fa uso delle suite come la precedente
versione
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({TestUno.class,
TestDue.class,
TestTre.class})
public class JUnit4Suite { }
20. Timer
● È possibile ora controllare se un test impiega troppo
tempo oppure va in timeout
1000 = 1 s
@Test (timeout = 100)
public void provaConnessione(){
...
url.openConnection();
...
}
21. Ignorare i test
● In JUnit 3.8.1, tutti i metodi che non iniziano per “test”
vengono ignorati dal framework
● JUnit 4.x consente di annotarli come @Ignore
● I TestRunner tengono conto dei test ignorati, per non
perderli in mezzo al codice
@Ignore
@Test
public void metodoIgnorato(){
...
}
22. Altre novità
● Aggiunti metodi assert per testare i vettori
– assertEquals(Object[], Object[])
● Due annotazioni comode per le fixture uniche per classe
– @BeforeClass e @AfterClass (devono essere statici)
● Nuovo TestRunner, eliminata swingui
23. Test Parametrici
● JUnit 4.x dispone di una soluzione elegante al problema
dei test da eseguire con un numero molto esteso di
combinazioni di parametri in ingresso
● Si utilizzano così:
– si crea il metodo @Test parametrico
– si creano tante variabili d'istanza quanti sono i nomi sono
quelli dei parametri di @Test
– si crea un costruttore del test che ha per parametri la n-
upla identica alle variabili d'istanza
– si crea un metodo statico @Parameters che deve restituire
una Collection (contiene le n-uple di parametri con i
valori)
– si annota la classe con @RunWith(Parameterized.class)
25. Esempio (2/2)
@Parameters
public static Collection creaParametri(){
...return Arrays.asList(new Object[][] {
{1, “pippo” },
{100, “paperino”},
{1000, “pluto”}}});
}
@Test
public void testParametrico(){
...//qui uso par1 e par2
}
}
26. Ant e JUnit 4.x
● Alcuni problemi con Ant <1.7
● Occorre aggiungere al TestCase il seguente metodo:
public static junit.framework.Test suite(){
return new JUnit4TestAdapter(
RegularExpressionTest.class);
}
27. Licenza Creative Commons (sunto)
Attribuzione-Non commerciale-Condividi allo stesso modo
3.0 Unported
Tu sei libero di modificare, riprodurre, distribuire, comunicare al pubblico, esporre in
pubblico, rappresentare, eseguire e recitare quest'opera.
Alle seguenti condizioni:
● Attribuzione. Devi attribuire la paternità dell'opera nei modi indicati dall'autore
o da chi ti ha dato l'opera in licenza e in modo tale da non suggerire che essi
avallino te o il modo in cui tu usi l'opera.
● Non commerciale. Non puoi usare quest'opera per fini commerciali.
● Condividi allo stesso modo. Se alteri o trasformi quest'opera, o se la usi per
crearne un'altra, puoi distribuire l'opera risultante solo con una licenza identica o
equivalente a questa.
● Testo completo della licenza completa su:
http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode