27
JUnit (2) Ing. Fabrizio Gianneschi Java User Group Sardegna Onlus http://www.jugsardegna.org Java Unit Testing

Java Unit Testing - JUnit (2)

Embed Size (px)

DESCRIPTION

Java Unit Testing - part 3

Citation preview

Page 1: Java Unit Testing - JUnit (2)

JUnit (2)

Ing. Fabrizio GianneschiJava User Group Sardegna Onlus

http://www.jugsardegna.org

Java Unit Testing

Page 2: Java Unit Testing - JUnit (2)

JUnit (2)http://www.junit.org

Page 3: Java Unit Testing - JUnit (2)

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

Page 4: Java Unit Testing - JUnit (2)

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

Page 5: Java Unit Testing - JUnit (2)

Esempio

private Connection myConn; protected void setUp() throws Exception{ MyConn = DatabaseStub.createConnection();

}...

public void testXyz(){ Statement st = myConn.createStatement(); ...

}protected void tearDown() throws Exception{ myConn.close();}

Page 6: Java Unit Testing - JUnit (2)

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

Page 7: Java Unit Testing - JUnit (2)

TestSetuppublic 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(){ ...}}

Page 8: Java Unit Testing - JUnit (2)

Esercizi

Page 9: Java Unit Testing - JUnit (2)

Differenze tra Junit 3.8.x e 4.x

Page 10: Java Unit Testing - JUnit (2)

Cambio package

● Le classi principali stanno ora in org.junit.* anziché in junit.framework.*

JUnit 3.8.1:

package com.mycompany;

import junit.framework.*;

...

Page 11: Java Unit Testing - JUnit (2)

Cambio package

● Le classi principali stanno ora in org.junit.* anziché in junit.framework.*

JUnit 4.x:

package com.mycompany;

import org.junit.*;

...

Page 12: Java Unit Testing - JUnit (2)

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{ ...}

Page 13: Java Unit Testing - JUnit (2)

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 ....}

Page 14: Java Unit Testing - JUnit (2)

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(){...}...

Page 15: Java Unit Testing - JUnit (2)

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(){...}...

Page 16: Java Unit Testing - JUnit (2)

Ancora più espressività

● Anche i metodi setUp() e tearDown() sono sostituibili con metodi annotati

public void setUp() --------> @Before

public void tearDown() --------> @After

Esempio:

@Beforepublic void initResources(){...}

Page 17: Java Unit Testing - JUnit (2)

Problema

● Se le classi di test non ereditano più da TestCase, come invocare le asserzioni?

In realtà, sta chiamandoAssert.assertEquals !

Soluzione:Grazie agli import statici di Java 5, rimane tutto come prima!

import static org.junit.Assert.*;...@Testpublic void myTestMethod(){ ... assertEquals(obj1,obj2);}

Page 18: Java Unit Testing - JUnit (2)

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(){ ...}

Page 19: Java Unit Testing - JUnit (2)

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 { }

Page 20: Java Unit Testing - JUnit (2)

Timer

● È possibile ora controllare se un test impiega troppo tempo oppure va in timeout

@Test (timeout = 100)public void provaConnessione(){ ... url.openConnection(); ...}

1000 = 1 s

Page 21: Java Unit Testing - JUnit (2)

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@Testpublic void metodoIgnorato(){ ...}

Page 22: Java Unit Testing - JUnit (2)

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

Page 23: Java Unit Testing - JUnit (2)

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)

Page 24: Java Unit Testing - JUnit (2)

Esempio (1/2)@RunWith(Parameterized.class)public class ParameterTest{ private int par1; private String par2; public ParameterTest(int p1, String p2){ par1 = p1; par2 = p2; }

Page 25: Java Unit Testing - JUnit (2)

Esempio (2/2)@Parameterspublic static Collection creaParametri(){ ...return Arrays.asList(new Object[][] { {1, “pippo” }, {100, “paperino”}, {1000, “pluto”}}});}

@Test public void testParametrico(){ ...//qui uso par1 e par2 }}

Page 26: Java Unit Testing - JUnit (2)

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);

}

Page 27: Java Unit Testing - JUnit (2)

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 inpubblico, 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