SlideShare a Scribd company logo
1 of 38
Download to read offline
Java Unit Testing



In-container and database Testing


    Ing. Fabrizio Gianneschi
Java User Group Sardegna Onlus
  http://www.jugsardegna.org
Test in-container
Quando usare i mock object?
●   I mock sono consigliati quando l'oggetto reale da
    rimpiazzare:
    –   ha un comportamento non deterministico
    –   è difficile da inizializzare
    –   ha un comportamento difficile da riprodurre
    –   è lento
    –   ha un'interfaccia grafica
    –   non esiste
●   Oppure, quando il test necessita di invocare dei metodi
    che nell'oggetto reale non esistono
Usare oggetti mock
●   Abbiamo già visto come usare semplici oggetti mock
●   Crearne di numerosi è però complicato
●   Per fortuna, esistono numerosi framework già pronti
    all'uso:
    –   JMock
    –   EasyMock
    –   rMock
●   In generale, i mock sono utili per effettuare test out-
    container... ma possono essere usati anche per i test in-
    container
●   Il problema è sempre il solito: controllare le dipendenze
In-Container testing
●   È il testing “a motore acceso”
●   Si testano componenti il cui ciclo di vita è gestito da un
    soggetto terzo (il container)
●   Ci sono casi, infatti, in cui non è possibile fare a meno
    del container (es: HttpSession...)
●   Oppure, quando non abbiamo stub abbastanza buoni o
●   Tool: Cactus
Cactus
●   Cactus è un framework per il testing di componenti J2EE
●   Tipicamente, test unitari
●   Spesso usato con Jetty, servlet container leggero e
    veloce
    –   parte in circa 1s (Tomcat e altri impiegano di più)
●   Poggia su JUnit ed estende alcuni suoi metodi
●   La filosofia è simile a JUnit (setup, esecuzione,
    teardown...) ma distribuita tra client e server
Nota
●   Cactus è disponibile nella versione 1.7.2
    –   per container J2EE 1.2
    –   per container J2EE 1.3
●   Non è disponibile espressamente per J2EE 1.4, anche se
    si può usare quello per la versione per la 1.3
●   Testato con Tomcat 5.x
●   NO JavaEE 5 --e non ci sono date, al riguardo :-(


●   Alternative: JUnitEE, HttpUnit (incluso in Cactus),
    EJB3Unit...
Purtroppo...
●   Non è ancora compatibile con JUnit 4.x, anche se c'è un
    piccolo workaround...


“I found out that it's possible to run the JUnit 4.x (annotated) tests with

Cactus 1.7.2 minimaly with functionality of JUnit 3.8 tests.

It's need to use: JUnit4TestAdapter that automatically makes JUnit 3.8

compatible test from JUnit 4.x test.

There is only problem with displaying names of the tests but it's easy to

repair it in source class (JUnitVersionHelper) of Cactus.”
Workaround
import junit.framework.JUnit4TestAdapter;
...
public static junit.framework.Test suite() {
    return new Junit4TestAdapter(<classname>.class);
}
...
Sul client
●   C'è la console
●   Vengono eseguiti i metodi di inizializzazione
    –   beginXXX e endXXX
●   Sono esposte interfacce che ricalcano request,
    response, sessione...
●   Serializza la chiamata e la spedisce ad un
    ProxyRedirector sul server
●   In risposta, vengono raccolti gli output
●setUp()                                         Classi del container
   ●testXxx()    TestCase sul server             Classi del container
   ●tearDown()
                                                         Classi del container
                                             cfg
                                        (es: web.xml)
Server JVM        Proxy redirector


Client JVM                   HttpRequest




                                           ●beginXxx()
                  TestCase sul client      ●endXxx()
Sul server
●   Vive il Proxy redirector
    –   ServletTestRedirector
    –   JSPTestRedirector
    –   FilterTestRedirector
●   “Sente” la chiamata, deserializza le informazioni e le
    interpreta
    –   capisce che TestCase invocare (testXxx() )
●   Lo inizializza con setUp()
●   Lo finalizza con tearDown()
●   Vivono gli oggetti del container
Sul client (configurazione)
●   Deve essere resa disponibile una proprietà di sistema
    cactus.contextURL per consentire a Cactus di
    chiamare il container
●   Tre modi:
    –   via command line
        ( java ... -Dcactus.contextURL=http://myhost/mypath )
    –   via System.setProperty() nel codice di inizializzazione
        dei test
    –   via file di configurazione (cactus.properties) messo nel
        classpath (equivale alle properties)
●   Allo stesso modo, va specificato il nome della classe da
    usare come Proxy
    –   cactus.servletRedirectorName = ServletTestRedirector
Sul server (configurazione)
●   Va modificato il web.xml con opportune entry per i
    proxy utilizzati:
<servlet>
  <servlet-name>ServletTestRedirector</servlet-name>
    <servlet-class>
      org.apache.cactus.server.ServletTestRedirector
    </servlet-class>
</servlet>
...
<servlet-mapping>
  <servlet-name>ServletTestRedirector</servlet-name>
  <url-pattern>/ServletTestRedirector</url-pattern>
</servlet-mapping>
Sul server (attenzione)
●   I componenti di Cactus non andrebbero inclusi nella
    distribuzione in produzione
    –   rimarrebbero disponibili dall'esterno, con gravi problemi di
        sicurezza
●   Ricordarsi di modificare il web.xml al momento del
    deploy!
    –   Sugg.: Usare un web.xml parametrico, modificato da Ant
        quando serve
    –   Nota: usare due web.xml differenti prima o poi porta al
        disallineamento
●   http://jakarta.apache.org/cactus/faq.html#faq_webxml_test_prod
Test di Servlet e JSP
Testare le servlet
●   Cactus mette a disposizione una serie di oggetti impliciti
●   Tali oggetti hanno interfacce conformi alla Servlet API
    ma l'implementazione è wrappata da Cactus
    –   request
         ● request.setURL(host, ctx, path)

         ● request.addCookie(name, value)

         ● request.setRemoteUser(...) / .setHost(...)

         ● request.setRemoteIPAddres(...)


    –   config
         ● config.setInitParameter / .setServletName


    –   config.getServletWrapper()
●   Non wrappati, ma a disposizione
    –   response
    –   session
Esercizio
●   Creare una servlet di controllo del flusso
●   La servlet controlla la presenza di un parametro page
    nella request
●   page rappresenta il nome di una pagina da caricare
●   inserisce un attributo nella request
    –   Se page inizia per “/private/”, il valore dell'attributo è il
        nome della JSP di autenticazione
    –   Altrimenti, mette page
●   Verificare il funzionamento con Cactus
Esercizio
●   Modificare la servlet precedente in modo tale che
    effettui direttamente la redirezione
     –   non solo controllo, ma anche dispatching...
●   Testare con Cactus... si può?
●    Sì, ma non direttamente:
    ● Posso testare l'output della servlet

    ● Posso verificare che il target della redirezione esista
Esercizio
●   Testare che una servlet riceva correttamente i dati di un
    form multipart/data
●   Per la spedizione dei dati dal TestCase:
●   http://jakarta.apache.org/cactus/faq.html#faq_send_multipart
●   Per la ricezione dei dati dalla servlet:
     – Si può utilizzare la libreria Commons FileUpload
     – http://www.javastaff.com/article.php?
       story=20060628011504263
Testare le JSP
●   A differenza delle Servlet, che dovrebbero contenere
    solamente logica, le JSP possono presentare anche
    grafica
●   Pertanto, si distinguono 3 casi:
    –   test dell'HTML / XHTML generato a seguito della logica
    –   test delle TagLib JSP
    –   test della logica, ma in isolamento
Caso 1: test dell'HTML
●   Banale, estende ServletTestCase
●   Dal metodo testXXX si invoca il dispatching alla JSP
RequestDispatcher disp = config.getServletContext().
              getRequestDispatcher(quot;/pagina.jspquot;);
disp.forward(request, response);


●   Nel metodo endXXX si verifica l'output nella response
●   Esistono però tool più specializzati
Caso 2: TagLib
●   Sono classi Java, che vivono in un contesto di pagina
●   Il testcase estende JspTestCase
●   Si utilizzano gli oggetti impliciti per inizializzare il test
●   Si crea un'istanza del tag e le si passa l'oggetto implic.
    pageContext
●   Si chiamano i metodi del CdV del tag
    –   doStartTag(), doAfterBody(), doEndTag()...
●   Si verifica che restituiscano il valore corretto
●   Si controlla l'output (HTML, ...) del tag nel metodo
    endXXX()
Caso 3: test logico
●   Le JSP in genere utilizzano JavaBean creati dalle Servlet,
    che glieli passano attraverso la request. Perciò:
●   Si estende JSPTestCase
●   Nel testXXX(), si creano tutti i bean necessari e si
    mettono nella request.
●   Si fa il forward alla JSP
●   Nel endXXX(), si controlla l'output
Test e basi di dati
Problemi
●   Il test dei db, o con i db, è uno dei più complessi
●   Il db è un'entità esterna
    –   No codice Java. No refactoring...
    –   Altri tool, altre interfacce, altre policy
●   Il db è lento
●   Il db è spesso condiviso
    –   i test rischiano di sovrapporsi
●   Il db è distribuito
    –   Quali e quanti db testare?
●   Il db è persistente
    –   lo stato del db influisce sui test
Considerazioni
●   Un buon db test deve essere autosufficiente
    –   non deve essere sensibile, nel bene o nel male, alle
        modifiche al db effettuate da un altro test
●   Un buon test crea tutti i dati che gli servono
    –   il db deve essere inizializzato ad uno stato noto prima di
        eseguire il test
●   Serve quindi almeno un db completamente separato da
    quello di produzione
●   Non è necessario che il test ripulisca il db quando ha
    terminato
●   Non è necessario cancellare / creare tutto il db per ogni
    test
“You need four databases”
●   Un'organizzazione con quattro livelli di db consente un
    testing efficace



        DEV


                   Integrazione   Pre-produzione   Produzione
DEV


        DEV
Level one: development
●   Ogni sviluppatore dovrebbe avere un db a sua
    disposizione
    –   Preferibilmente in locale
●   Lo sviluppatore dovrebbe avere libertà totale su
    start/stop/manage della propria istanza
●   I dati sono privi di utilità e significato pratico, se non per
    i test
●   Il db può rimanere in uno stato inconsistente
●   Per ragioni di efficienza, è preferibile utilizzare db
    lightweight
    –   In-memory db (Hypersonic, Derby...)
Level two: integration
●   È il livello dove si eseguono i test d'integrazione e
    funzionali
●   I responsabili sono sempre gli sviluppatori
●   I dati sono ancora poco significativi
●   Lo stato precedente del db non è significativo
●   Le differenze di schema o errori vengono subito al
    pettine e vanno armonizzate
Level three: pre-production
●   Qui si testa l'ultima versione integrata funzionate, con
    dati (o partizioni di db) reali, provenienti dal db di
    produzione
●   Prima dei test, il db va riallineato con la produzione
●   La responsabilità di eseguire i test è del Q&A
●   Non si fa integrazione.
●   Test di carico e di accettazione
Level four: production
●   Dati reali
●   Nessun testing qui!
Java Db Testing
●   Serve quindi qualcosa che semplifichi ed automatizzi il
    pià possibile:
    –   lo start start/stop dell'istanza del db
    –   le modifiche allo schema
    –   l'immissione e la cancellazione dei valori d'inizializzazione
    –   ripeta le operazioni precedenti per ogni test case
●   Per aiutarci in questo, esiste DbUnit
    –   basato su JUnit
Caso tipico: Business Logic o Data
Access Logic da testare
●   Approccio suggerito:
    –   Mantenere i dati di inizializzazione su file (xml, plain text,
        excel, ...) o hard coded
●   Database In-Memory
●   Inizializzare il db con dbUnit
●   Invocare la logica da testare nel corpo del test
●   Verificare il risultato:
    –   verifica di comportamento della logica (può essere fatta
        anche senza dbUnit, con un mock / stub!!)
    –   verifica delle azioni compiute sul db
         ● sempre con dbUnit, o via codice con delle SELECT
Importante
●   NON concentrarsi a testare il framework di persistenza
    –   Hibernate, iBatis....
●   Il test è della propria applicazione, non di quelle degli
    altri
Esercizi
●   Testare una classe di business che scrive direttamente
    sul database
●   La classe ha un metodo che legge un campo di una
    tabella e ne aggiorna il valore in base ad un criterio da
    lei stabilito (es: se maggiorenne pone il flag a Y)
●   Esercizio 2:
    –   Introdurre l'uso di un Data Access Object (DAO)
    –   Testare anche il DAO
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

More Related Content

What's hot

PowerMock TDD User Group Milano
PowerMock TDD User Group MilanoPowerMock TDD User Group Milano
PowerMock TDD User Group MilanoMassimo Groppelli
 
Unit Test di Gabriele Seroni
Unit Test di Gabriele SeroniUnit Test di Gabriele Seroni
Unit Test di Gabriele SeroniGiuneco S.r.l
 
Introduzione al Test Driven Development
Introduzione al Test Driven DevelopmentIntroduzione al Test Driven Development
Introduzione al Test Driven DevelopmentEnnio Masi
 
Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)Carmelantonio Zolfo
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Developmentsazilla
 
Tdd.Every.Where.21012012
Tdd.Every.Where.21012012Tdd.Every.Where.21012012
Tdd.Every.Where.21012012LEGALDESK
 
Lezione 8: Design Pattern Comportamentali
Lezione 8: Design Pattern ComportamentaliLezione 8: Design Pattern Comportamentali
Lezione 8: Design Pattern ComportamentaliAndrea Della Corte
 
Come automatizzare i test con Selenium IDE
Come automatizzare i test con Selenium IDECome automatizzare i test con Selenium IDE
Come automatizzare i test con Selenium IDEStefano Trojani
 
Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Davide Carboni
 
Lezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern StrutturaliLezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern StrutturaliAndrea Della Corte
 
Lezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e SubversionLezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e SubversionAndrea Della Corte
 
Lezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme ProgrammingLezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme ProgrammingAndrea Della Corte
 
DotNetCampus - Continuous Integration con Sql Server
DotNetCampus - Continuous Integration con Sql ServerDotNetCampus - Continuous Integration con Sql Server
DotNetCampus - Continuous Integration con Sql ServerAlessandro Alpi
 

What's hot (19)

Unit testing 101
Unit testing 101Unit testing 101
Unit testing 101
 
PowerMock TDD User Group Milano
PowerMock TDD User Group MilanoPowerMock TDD User Group Milano
PowerMock TDD User Group Milano
 
Unit Test di Gabriele Seroni
Unit Test di Gabriele SeroniUnit Test di Gabriele Seroni
Unit Test di Gabriele Seroni
 
Applicazioni native in java
Applicazioni native in javaApplicazioni native in java
Applicazioni native in java
 
Concurrency
ConcurrencyConcurrency
Concurrency
 
Introduzione al Test Driven Development
Introduzione al Test Driven DevelopmentIntroduzione al Test Driven Development
Introduzione al Test Driven Development
 
Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Development
 
Tdd.Every.Where.21012012
Tdd.Every.Where.21012012Tdd.Every.Where.21012012
Tdd.Every.Where.21012012
 
Lezione 8: Design Pattern Comportamentali
Lezione 8: Design Pattern ComportamentaliLezione 8: Design Pattern Comportamentali
Lezione 8: Design Pattern Comportamentali
 
Il testing con zend framework
Il testing con zend frameworkIl testing con zend framework
Il testing con zend framework
 
Design Pattern
Design PatternDesign Pattern
Design Pattern
 
Come automatizzare i test con Selenium IDE
Come automatizzare i test con Selenium IDECome automatizzare i test con Selenium IDE
Come automatizzare i test con Selenium IDE
 
Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)
 
Lezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern StrutturaliLezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern Strutturali
 
Lezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e SubversionLezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e Subversion
 
Lezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme ProgrammingLezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme Programming
 
Java OCA teoria 1
Java OCA teoria 1Java OCA teoria 1
Java OCA teoria 1
 
DotNetCampus - Continuous Integration con Sql Server
DotNetCampus - Continuous Integration con Sql ServerDotNetCampus - Continuous Integration con Sql Server
DotNetCampus - Continuous Integration con Sql Server
 

Similar to Java Unit Testing - In container and database testing

Presentazione Testing automatizzato
Presentazione Testing automatizzatoPresentazione Testing automatizzato
Presentazione Testing automatizzatoangelolu
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacyTommaso Torti
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Developmentsazilla
 
Installing Apache tomcat with Netbeans
Installing Apache tomcat with NetbeansInstalling Apache tomcat with Netbeans
Installing Apache tomcat with NetbeansDavide Nardone
 
Drupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e DrupalDrupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e DrupalDrupalDay
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Railsjekil
 
Laboratorio Di Basi Di Dati 08 Il Web Server Apache
Laboratorio Di  Basi Di  Dati 08  Il  Web Server  ApacheLaboratorio Di  Basi Di  Dati 08  Il  Web Server  Apache
Laboratorio Di Basi Di Dati 08 Il Web Server Apacheguestbe916c
 
Webbit 2004: Tiger, java
Webbit 2004: Tiger, javaWebbit 2004: Tiger, java
Webbit 2004: Tiger, javaMatteo Baccan
 
Laboratorio Di Basi Di Dati 02 Il D B M S My S Q L
Laboratorio Di  Basi Di  Dati 02  Il  D B M S  My S Q LLaboratorio Di  Basi Di  Dati 02  Il  D B M S  My S Q L
Laboratorio Di Basi Di Dati 02 Il D B M S My S Q Lguestbe916c
 
Phpday 2009 php e java
Phpday 2009 php e javaPhpday 2009 php e java
Phpday 2009 php e javaMatteo Baccan
 

Similar to Java Unit Testing - In container and database testing (20)

Presentazione Testing automatizzato
Presentazione Testing automatizzatoPresentazione Testing automatizzato
Presentazione Testing automatizzato
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacy
 
Corso Java 2 - AVANZATO
Corso Java 2 - AVANZATOCorso Java 2 - AVANZATO
Corso Java 2 - AVANZATO
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Development
 
Java lezione 17
Java lezione 17Java lezione 17
Java lezione 17
 
Installing Apache tomcat with Netbeans
Installing Apache tomcat with NetbeansInstalling Apache tomcat with Netbeans
Installing Apache tomcat with Netbeans
 
Il testing con zend framework
Il testing con zend frameworkIl testing con zend framework
Il testing con zend framework
 
Ajax - Presente e futuro delle applicazioni web
Ajax - Presente e futuro delle applicazioni webAjax - Presente e futuro delle applicazioni web
Ajax - Presente e futuro delle applicazioni web
 
Portlet JSR168/286
Portlet JSR168/286Portlet JSR168/286
Portlet JSR168/286
 
Drupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e DrupalDrupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e Drupal
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Rails
 
Powerful asp.net 4 e ie9
Powerful asp.net 4 e ie9Powerful asp.net 4 e ie9
Powerful asp.net 4 e ie9
 
Laboratorio Di Basi Di Dati 08 Il Web Server Apache
Laboratorio Di  Basi Di  Dati 08  Il  Web Server  ApacheLaboratorio Di  Basi Di  Dati 08  Il  Web Server  Apache
Laboratorio Di Basi Di Dati 08 Il Web Server Apache
 
Java lezione 14
Java lezione 14Java lezione 14
Java lezione 14
 
Many Designs Elements
Many Designs ElementsMany Designs Elements
Many Designs Elements
 
SCBCD 1. generic ejb
SCBCD 1. generic ejbSCBCD 1. generic ejb
SCBCD 1. generic ejb
 
Php mysql3
Php mysql3Php mysql3
Php mysql3
 
Webbit 2004: Tiger, java
Webbit 2004: Tiger, javaWebbit 2004: Tiger, java
Webbit 2004: Tiger, java
 
Laboratorio Di Basi Di Dati 02 Il D B M S My S Q L
Laboratorio Di  Basi Di  Dati 02  Il  D B M S  My S Q LLaboratorio Di  Basi Di  Dati 02  Il  D B M S  My S Q L
Laboratorio Di Basi Di Dati 02 Il D B M S My S Q L
 
Phpday 2009 php e java
Phpday 2009 php e javaPhpday 2009 php e java
Phpday 2009 php e java
 

Recently uploaded

Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Associazione Digital Days
 
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Associazione Digital Days
 
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Associazione Digital Days
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Associazione Digital Days
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Associazione Digital Days
 
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Associazione Digital Days
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Associazione Digital Days
 
Programma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoProgramma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoQuotidiano Piemontese
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Associazione Digital Days
 

Recently uploaded (9)

Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
 
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
 
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
 
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
 
Programma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoProgramma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 Torino
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
 

Java Unit Testing - In container and database testing

  • 1. Java Unit Testing In-container and database Testing Ing. Fabrizio Gianneschi Java User Group Sardegna Onlus http://www.jugsardegna.org
  • 3. Quando usare i mock object? ● I mock sono consigliati quando l'oggetto reale da rimpiazzare: – ha un comportamento non deterministico – è difficile da inizializzare – ha un comportamento difficile da riprodurre – è lento – ha un'interfaccia grafica – non esiste ● Oppure, quando il test necessita di invocare dei metodi che nell'oggetto reale non esistono
  • 4. Usare oggetti mock ● Abbiamo già visto come usare semplici oggetti mock ● Crearne di numerosi è però complicato ● Per fortuna, esistono numerosi framework già pronti all'uso: – JMock – EasyMock – rMock ● In generale, i mock sono utili per effettuare test out- container... ma possono essere usati anche per i test in- container ● Il problema è sempre il solito: controllare le dipendenze
  • 5. In-Container testing ● È il testing “a motore acceso” ● Si testano componenti il cui ciclo di vita è gestito da un soggetto terzo (il container) ● Ci sono casi, infatti, in cui non è possibile fare a meno del container (es: HttpSession...) ● Oppure, quando non abbiamo stub abbastanza buoni o ● Tool: Cactus
  • 6. Cactus ● Cactus è un framework per il testing di componenti J2EE ● Tipicamente, test unitari ● Spesso usato con Jetty, servlet container leggero e veloce – parte in circa 1s (Tomcat e altri impiegano di più) ● Poggia su JUnit ed estende alcuni suoi metodi ● La filosofia è simile a JUnit (setup, esecuzione, teardown...) ma distribuita tra client e server
  • 7. Nota ● Cactus è disponibile nella versione 1.7.2 – per container J2EE 1.2 – per container J2EE 1.3 ● Non è disponibile espressamente per J2EE 1.4, anche se si può usare quello per la versione per la 1.3 ● Testato con Tomcat 5.x ● NO JavaEE 5 --e non ci sono date, al riguardo :-( ● Alternative: JUnitEE, HttpUnit (incluso in Cactus), EJB3Unit...
  • 8. Purtroppo... ● Non è ancora compatibile con JUnit 4.x, anche se c'è un piccolo workaround... “I found out that it's possible to run the JUnit 4.x (annotated) tests with Cactus 1.7.2 minimaly with functionality of JUnit 3.8 tests. It's need to use: JUnit4TestAdapter that automatically makes JUnit 3.8 compatible test from JUnit 4.x test. There is only problem with displaying names of the tests but it's easy to repair it in source class (JUnitVersionHelper) of Cactus.”
  • 9. Workaround import junit.framework.JUnit4TestAdapter; ... public static junit.framework.Test suite() { return new Junit4TestAdapter(<classname>.class); } ...
  • 10. Sul client ● C'è la console ● Vengono eseguiti i metodi di inizializzazione – beginXXX e endXXX ● Sono esposte interfacce che ricalcano request, response, sessione... ● Serializza la chiamata e la spedisce ad un ProxyRedirector sul server ● In risposta, vengono raccolti gli output
  • 11. ●setUp() Classi del container ●testXxx() TestCase sul server Classi del container ●tearDown() Classi del container cfg (es: web.xml) Server JVM Proxy redirector Client JVM HttpRequest ●beginXxx() TestCase sul client ●endXxx()
  • 12. Sul server ● Vive il Proxy redirector – ServletTestRedirector – JSPTestRedirector – FilterTestRedirector ● “Sente” la chiamata, deserializza le informazioni e le interpreta – capisce che TestCase invocare (testXxx() ) ● Lo inizializza con setUp() ● Lo finalizza con tearDown() ● Vivono gli oggetti del container
  • 13. Sul client (configurazione) ● Deve essere resa disponibile una proprietà di sistema cactus.contextURL per consentire a Cactus di chiamare il container ● Tre modi: – via command line ( java ... -Dcactus.contextURL=http://myhost/mypath ) – via System.setProperty() nel codice di inizializzazione dei test – via file di configurazione (cactus.properties) messo nel classpath (equivale alle properties) ● Allo stesso modo, va specificato il nome della classe da usare come Proxy – cactus.servletRedirectorName = ServletTestRedirector
  • 14. Sul server (configurazione) ● Va modificato il web.xml con opportune entry per i proxy utilizzati: <servlet> <servlet-name>ServletTestRedirector</servlet-name> <servlet-class> org.apache.cactus.server.ServletTestRedirector </servlet-class> </servlet> ... <servlet-mapping> <servlet-name>ServletTestRedirector</servlet-name> <url-pattern>/ServletTestRedirector</url-pattern> </servlet-mapping>
  • 15. Sul server (attenzione) ● I componenti di Cactus non andrebbero inclusi nella distribuzione in produzione – rimarrebbero disponibili dall'esterno, con gravi problemi di sicurezza ● Ricordarsi di modificare il web.xml al momento del deploy! – Sugg.: Usare un web.xml parametrico, modificato da Ant quando serve – Nota: usare due web.xml differenti prima o poi porta al disallineamento ● http://jakarta.apache.org/cactus/faq.html#faq_webxml_test_prod
  • 16.
  • 18. Testare le servlet ● Cactus mette a disposizione una serie di oggetti impliciti ● Tali oggetti hanno interfacce conformi alla Servlet API ma l'implementazione è wrappata da Cactus – request ● request.setURL(host, ctx, path) ● request.addCookie(name, value) ● request.setRemoteUser(...) / .setHost(...) ● request.setRemoteIPAddres(...) – config ● config.setInitParameter / .setServletName – config.getServletWrapper() ● Non wrappati, ma a disposizione – response – session
  • 19. Esercizio ● Creare una servlet di controllo del flusso ● La servlet controlla la presenza di un parametro page nella request ● page rappresenta il nome di una pagina da caricare ● inserisce un attributo nella request – Se page inizia per “/private/”, il valore dell'attributo è il nome della JSP di autenticazione – Altrimenti, mette page ● Verificare il funzionamento con Cactus
  • 20. Esercizio ● Modificare la servlet precedente in modo tale che effettui direttamente la redirezione – non solo controllo, ma anche dispatching... ● Testare con Cactus... si può? ● Sì, ma non direttamente: ● Posso testare l'output della servlet ● Posso verificare che il target della redirezione esista
  • 21. Esercizio ● Testare che una servlet riceva correttamente i dati di un form multipart/data ● Per la spedizione dei dati dal TestCase: ● http://jakarta.apache.org/cactus/faq.html#faq_send_multipart ● Per la ricezione dei dati dalla servlet: – Si può utilizzare la libreria Commons FileUpload – http://www.javastaff.com/article.php? story=20060628011504263
  • 22. Testare le JSP ● A differenza delle Servlet, che dovrebbero contenere solamente logica, le JSP possono presentare anche grafica ● Pertanto, si distinguono 3 casi: – test dell'HTML / XHTML generato a seguito della logica – test delle TagLib JSP – test della logica, ma in isolamento
  • 23. Caso 1: test dell'HTML ● Banale, estende ServletTestCase ● Dal metodo testXXX si invoca il dispatching alla JSP RequestDispatcher disp = config.getServletContext(). getRequestDispatcher(quot;/pagina.jspquot;); disp.forward(request, response); ● Nel metodo endXXX si verifica l'output nella response ● Esistono però tool più specializzati
  • 24. Caso 2: TagLib ● Sono classi Java, che vivono in un contesto di pagina ● Il testcase estende JspTestCase ● Si utilizzano gli oggetti impliciti per inizializzare il test ● Si crea un'istanza del tag e le si passa l'oggetto implic. pageContext ● Si chiamano i metodi del CdV del tag – doStartTag(), doAfterBody(), doEndTag()... ● Si verifica che restituiscano il valore corretto ● Si controlla l'output (HTML, ...) del tag nel metodo endXXX()
  • 25. Caso 3: test logico ● Le JSP in genere utilizzano JavaBean creati dalle Servlet, che glieli passano attraverso la request. Perciò: ● Si estende JSPTestCase ● Nel testXXX(), si creano tutti i bean necessari e si mettono nella request. ● Si fa il forward alla JSP ● Nel endXXX(), si controlla l'output
  • 26. Test e basi di dati
  • 27. Problemi ● Il test dei db, o con i db, è uno dei più complessi ● Il db è un'entità esterna – No codice Java. No refactoring... – Altri tool, altre interfacce, altre policy ● Il db è lento ● Il db è spesso condiviso – i test rischiano di sovrapporsi ● Il db è distribuito – Quali e quanti db testare? ● Il db è persistente – lo stato del db influisce sui test
  • 28. Considerazioni ● Un buon db test deve essere autosufficiente – non deve essere sensibile, nel bene o nel male, alle modifiche al db effettuate da un altro test ● Un buon test crea tutti i dati che gli servono – il db deve essere inizializzato ad uno stato noto prima di eseguire il test ● Serve quindi almeno un db completamente separato da quello di produzione ● Non è necessario che il test ripulisca il db quando ha terminato ● Non è necessario cancellare / creare tutto il db per ogni test
  • 29. “You need four databases” ● Un'organizzazione con quattro livelli di db consente un testing efficace DEV Integrazione Pre-produzione Produzione DEV DEV
  • 30. Level one: development ● Ogni sviluppatore dovrebbe avere un db a sua disposizione – Preferibilmente in locale ● Lo sviluppatore dovrebbe avere libertà totale su start/stop/manage della propria istanza ● I dati sono privi di utilità e significato pratico, se non per i test ● Il db può rimanere in uno stato inconsistente ● Per ragioni di efficienza, è preferibile utilizzare db lightweight – In-memory db (Hypersonic, Derby...)
  • 31. Level two: integration ● È il livello dove si eseguono i test d'integrazione e funzionali ● I responsabili sono sempre gli sviluppatori ● I dati sono ancora poco significativi ● Lo stato precedente del db non è significativo ● Le differenze di schema o errori vengono subito al pettine e vanno armonizzate
  • 32. Level three: pre-production ● Qui si testa l'ultima versione integrata funzionate, con dati (o partizioni di db) reali, provenienti dal db di produzione ● Prima dei test, il db va riallineato con la produzione ● La responsabilità di eseguire i test è del Q&A ● Non si fa integrazione. ● Test di carico e di accettazione
  • 33. Level four: production ● Dati reali ● Nessun testing qui!
  • 34. Java Db Testing ● Serve quindi qualcosa che semplifichi ed automatizzi il pià possibile: – lo start start/stop dell'istanza del db – le modifiche allo schema – l'immissione e la cancellazione dei valori d'inizializzazione – ripeta le operazioni precedenti per ogni test case ● Per aiutarci in questo, esiste DbUnit – basato su JUnit
  • 35. Caso tipico: Business Logic o Data Access Logic da testare ● Approccio suggerito: – Mantenere i dati di inizializzazione su file (xml, plain text, excel, ...) o hard coded ● Database In-Memory ● Inizializzare il db con dbUnit ● Invocare la logica da testare nel corpo del test ● Verificare il risultato: – verifica di comportamento della logica (può essere fatta anche senza dbUnit, con un mock / stub!!) – verifica delle azioni compiute sul db ● sempre con dbUnit, o via codice con delle SELECT
  • 36. Importante ● NON concentrarsi a testare il framework di persistenza – Hibernate, iBatis.... ● Il test è della propria applicazione, non di quelle degli altri
  • 37. Esercizi ● Testare una classe di business che scrive direttamente sul database ● La classe ha un metodo che legge un campo di una tabella e ne aggiorna il valore in base ad un criterio da lei stabilito (es: se maggiorenne pone il flag a Y) ● Esercizio 2: – Introdurre l'uso di un Data Access Object (DAO) – Testare anche il DAO
  • 38. 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