JUnit in Action: riassunto del libro

JUnit in action

JUnit in Action

JUnit in Action (seconda edizione) è un libro che introduce il framework Java per il testing JUnit. Ovviamente per trattare una libreria sul testing il libro presenta anche una introduzione alla teoria del testing, con alcune best practice per l’unit testing (verso il quale è indirizzato JUnit) ed alcuni esempi pratici di utilizzo di JUnit assieme a sue estensioni (ad esempio Cactus per il testing di Servlet).

Se desiderate approfondire l’argomento, è possibile comprare il libro in versione cartacea JUnit in Action su Amazon (in lingua inglese).

Riassunto del libro

Il libro si apre con una introduzione a JUnit, spiegando che si tratta di un framework, cioè un’applicazione semi completa, che offre una struttura riusabile, una struttura comune condivisa tra le varie applicazioni finali costruite utilizzando il framework: gli sviluppatori incorporando il framework nelle loro applicazioni provvendono a costruirci sopra la propria logica di business e magari anche di presentazione, estendendolo.

La differenza tra un framework ed un toolkit è che quest’ultimo, pur offrendo sempre delle librerie/funzionalità utilizzate dagli sviluppatori, non prevede una struttura coerente sulla quale costruire le applicazioni, è solo un set di classi di utilità.

La teoria dell’Unit Testing

L’Unit Testing esamina il comportamento di una singola unità (nel caso della programmazione ad oggetti e quindi di Java, si tratta quasi sempre di un metodo). In questo riguardare una singola unità si contrappone ad Integration Test e Acceptance Test, che esaminano il comportamento di più unità assieme.

L’acceptance test spesso è fornito o comunque realizzato assieme al cliente finale, e può includere oltre ad un discorso funzionale anche aspetti di Look&Feel e performance. Tralasciando il Look&Feel, la parte funzionale si può testare con JUnit, anche la parte delle performance, ma per quello ci sono altri framework di testing più specifici (es. JMeter).

xUnit

E’ la sigla che individua una serie di framework, per vari linguaggi di programmazione, dedicati all’Unit Testing, tra cui appunto JUnit. Le caratteristiche di questi framework sono:

  • Possibilità di eseguire test indipendentemente uno dall’altro
  • Individuare e riprotare gli errori test per test
  • Possibilità di definire facilmente i test

JUnit

Rende possibile la definizione di test all’interno di classi che per convenzione vengono chiamate xxxTest (e sono chiamate Test Class o Test Case), e prevedono metodi che vanno annotati con l’annotazione @Test. Ogni metodo rappresenta il test di un metodo della class da testare. E’ possibile mettere assieme più classi di test in una Suite di Test, che sarà lanciata dal Test Runner, una classe che si occupa dell’esecuzione della Suite. Nota che utilizzando Eclipse non serve creare un Test Runner, esiste un plugin apposito che lancia direttamente le Test Class o le Test Suite.

All’interno di un test vado poi a definire i test utilizzando espressioni come

  • assertTrue
  • assertEquals
  • assertNotTrue
  • assertNotSame
  • assertArrayNotEquals
  • assertNotNull

Una suite si definisce tramite l’annotazione @SuiteClasses({NomePrimaClasseTest.class, NomeSecondaClasseTest.class,… }) , specificando anche con quale runner eseguirla @RunWith(MioRunner.class)

Annotazioni in JUnit

Detto che un Test è individuato da @Test, è possibile arricchire l’annotazione specificando:

  1. Un timeout (utile per test di performance) @Test(timeout=TIME_IN_MS)
  2. Il tipo di eccezione attesa @Test(expected=NomeEccezione.class)
  3. Di ignorare il test per ora, perchè magari lo si sta ancora costruendo, inserendo sotto l’annotazione @Test un’altra annotazione @Ignore(value=”Ignore for now blabla”)

Hamcrest

Hamcrest è una libreria che permette di definire test in maniera più semplice, evitando l’uso di operatori per leggere valori da array o di concatenazioni di OR e AND, es. (anyOf , ma anche molte altre)

Cobertura

E’ un tool che lavora assieme a JUnit per controllare la copertura del codice da parte dei nostri test: crea una copia delle classi e ne logga l’esecuzione per vedere quali porzioni di codice non vengono testate. Genera specifici report html.

Test di metodi complessi

Un metodo complesso difficilmente è isolato, probabilmente al suo interno utilizzerà altre classi, fornite come argomenti al metodo o attributi dell’oggetto. Per testare un tale metodo, ci sono principalmente tre alternative:

  • Istanziare gli oggetti reali nell’ambiente di test, creare un contesto verosimile magari all’interno di un metodo annotato con @Before. Nota che questa pratica non sempre è possibile, ad esempio potrebbero esserci oggetti che non hanno un costruttore esplicito (es. HttpSession o HttpRequest per testare una Servlet).
  • Realizzare una classe stub, che implementa una interfaccia o estende una certa classe, che restituisca dei valori statici, non dinamici, che permettano però di definire un test. Un tipo avanzato di stub potrebbe essere ottenuto utilizzando, e c’è un apposito esempio nel libro, l’istanziazione di un server Jetty che vada a predisporre una pagina statica, utilizzata dal modulo che poi voglio testare.
  • Realizzare una classe mock, utilizzando librerie quali EasyMock o JMock, che permettono di definire a runtime dei comportamenti che tali oggetti devono eseguire. Essendo la definizione dinamica, posso definire comportamenti diversi per la stessa classe in differenti test, mentre con gli stub avrei dovuto realizzare due classi diverse per ottenere la stessa cosa.
  • Se mi serve solo come parametro per la signature del metodo, posso creare un oggetto senza implementazione del tutto, un cosiddetto Dummy

Unit Testing all’interno di Application Container

Nel libro viene affrontato questo argomento, offrendo diverse soluzioni:

  • Creazione di Mock per HttpRequest, HttpSession, e tutte le altre classi coinvolte, e test delle classi direttamente
  • Esecuzione nel Servlet Container (test eseguiti lato client)
  • Esecuzione nel Servlet Container (test eseguiti lato server)

Le ultime due opzioni prevedono ovviamente l’utilizzo di programmi specifici, per i quali esistono comunque plugin per i più diffusi IDE ma che possono peggiorare le prestazioni del test. Il libro fa l’esempio di Cactus ed ha un capitolo apposito, ma il Libro è del 2011, e ad oggi il progetto Cactus è stato abbandonato ed è quindi consigliato migrare verso altri framework di testing, come ad esempio Arquillan.

E’ un peccato che Cactus sia stato abbandonato (non c’erano abbastanza volontari per seguire il progetto), era una estensione diretta di JUnit che ne riprendeva la sintassi ma era eseguibile all’interno di JEE/Servlet Container.

Unit Testing del presentation layer

Esistono estensioni specifiche, per esempio HTMLUnit (headless, esecuzione in un JVM) o Selenium (sfrutta i browser reali per registrare i test, tramite estensioni specifiche), oppure JSUnit.

Per ciascuna di queste estensioni il libro ha un capitoletto a parte dove vengono forniti esempi su come utilizzarle. Anche in questo caso, come nel caso di Cactus, emerge un pò i 2 anni di età del libro, dato che vengono utilizzate versioni vecchie, ma i progetti in questione non sono stati abbandonati come nel caso di Cactus, quindi non c’è nessun problema a riguardo, la sintassi non dovrebbe aver subito grandi modifiche nelle versioni aggiornate dei framework per il testing del presentation layer.

Altri tool

Per concludere, il libro parla anche di Tool che non si occupano solamente di testing, in particolare ha un capitolo dedicato ad Ant, uno a Maven e uno alla Continuous Integration e al Cruise Control.

Ant

E’ un build tool: esegue task ripetitivi impostati tramite un file xml (build file, uno per progetto).
Se ho un’applicazione semplice posso anche buildare tutto da eclipse, ma se ho più progetti che compongono una singola applicazione, il modo migliore è uno script Ant che gestisca tutto: build, testing, ecc.

Maven

E’ un altro build tool, vale il discorso fatto per Ant. Nel libro viene approfondito l’argomento e c’è un esempio di un file di configurazione pom.xml .

Continuous Integration

Ogni 15 minuti viene eseguito un checkout, build automatico ed i test (unit + integration). Esistono tool specifici per questo task, che possono anche essere eseguiti su macchine solo dedicate alla CI, ad esempio il tool esposto nel libro è Cruise Control.


Qui si conclude il mio “antipasto” del libro JUnit in Action, in vendita al miglior prezzo online su Amazon (in lingua inglese, non è presente una traduzione italiana del libro).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *