Cactus (sda)

Da Sinapsi.

Jump to: navigation, search

Contents

Programma della SDA

La SDA si articolerà come segue:

  • Introduzione su Cactus
  • Installazione di Cactus
  • Esempio di un piccolo test via Cactus
  • Altri sistemi di test (jameleon, ActiWATE)

Per maggiori informazioni sui singoli metodi si rimanda alla documentazione online fornita da Jakarta stessa.

Cosa è

Cactus è un framework per il testing sviluppato da Jakarta. È un insieme di librerie gratuite, sviluppate per velocizzare la scrittura di codice di testing per il lato server delle applicazioni web. Cactus si appoggia sul già collaudato framework JUnit, estendendolo con una serie di plugin e integrandosi direttamente nelle principali IDE di sviluppo (JBuilder ed Eclipse).

Come funziona

Cactus è stato sviluppato fondamentalmente per test di integrazione, ma è facilmente in grado, con le opportune estensioni, di svolgere test funzionali o anche di basso livello. In particolare si possono testare anche le applicazioni web sviluppate con Struts grazie all'apposita estensione StrutsTestCase.

La peculiarità di questo framework è la possibilità di testare l'applicazione "dall'interno", ovvero di poter testare tutti gli aspetti dell'applicazione, direttamente sull'application server sul quale è istanziata. Questo sistema viene definito testing in-Container, ed è un modo di provare l'applicazione "nel suo ambiente naturale". L'uso di Cactus non richiede la modifica delle classi e delle pagine già scritte, perché è possibile testare le singole classi e pagine come se fosse un qualunque utente a richiederle. Tutto questo è possibile grazie alle librerie di Cactus che devono essere caricate sul server prima di procedere al testing. Prima di ogni test, il client Cactus accede a queste librerie, e grazie a loro è in grado di porre l'applicazione in uno stato arbitrario. In seguito il client manda una richiesta opportunamente formattata all'applicazione e ne valuta la risposta. Cactus infatti mette a disposizione una serie di metodi per definire tutte le proprietà della richiesta che sarà poi inviata all'applicazione. Cactus è in grado di testare ogni aspetto dell'applicazione, dalla presentazione delle pagine jsp alle action, fino alle classi di servizio più remote. Inoltre esistono molte estensioni per poter testare gli aspetti più peculiari di ogni applicazione.

Immagine:Cactus archi.jpg

I vantaggi di poter testare l'applicazione direttamente sul suo application server con Cactus sono molteplici, ma ci sono alcuni limiti: le parti di applicazione da testare devono essere perlomeno in uno stato coerente e funzionante. Inoltre se si riscontra un errore in una classe che usa molte altre classi dell'applicazione, è necessario testare tutte le classi richieste per escludere la possibilità che l'errore provenga da una delle classi sottostanti. Questo comportamento forza sostanzialmente una programmazione di tipo bottom-up, si devono prima scrivere le classi di più "basso livello", testarle e poi procedere con le classi che su esse si poggiano. Infine c'è lo svantaggio di dover obbligatoriamente importare alcune librerie lato server per gestire il processo di testing: questo in linea di principio potrebbe portare a una "falsificazione" del risultato per quei test funzionali che vorrebbero trattare l'intero server senza alterare minimamente lo stato della sua configurazione, come ad esempio nel caso di test di applicazioni già in produzione.

Come si installa

Essendo un framework di supporto non c'è un comodo setup da eseguire, ma è necessario integrare le librerie di Cactus nell'applicazione che si vuole testare, per poi scrivere i test. Esistono effettivamente alcuni moduli già pronti per l'integrazione con Ants e con JBuilder, ma anch'essi richiedono comunque una serie di passaggi da effettuare manualmente. Prima di procedere è opportuno verificare di aver scaricato la versione corretta di Cactus, a seconda della versione di J2EE API su cui si basa l'applicazione da testare. Il framework di Cactus è strutturato secondo un modello client-server: insieme all'applicazione da testare devono essere caricate alcune librerie, che verranno usate dal client di test per interagire con le classi da testare come se fosse l'applicazione (in uno stato arbitrario) a chiamarle, o un utente nel caso delle pagine web.

Lato server

  • Per prima cosa è necessario importare nell'applicazione web le librerie indispensabili
    • cactus.jar
    • commons-httpclient.jar
    • commons-logging.jar
    • junit.jar
    • aspectjrt.jar

contenuti nella cartella /lib di Cactus. I rimanenti file .jar non sono tutti strettamente indispensabili, dipendono dal tipo di test che si desidera effettuare, e alcuni sono già compresi nell'application server. Se non si ha ancora una idea chiara dei test da effettuare, la soluzione più semplice è copiare tutto il contenuto della cartella /lib di Cactus in /WEB-INF/lib.

  • È consigliabile importare anche la libreria di StrutsTestCase, scaricabile a parte, che può essere molto utile per il testing di pagine contenenti elementi di struts.
  • È necessario modificare il file web.xml dell'applicazione aggiungendo le seguenti righe prima di ogni altra servlet:
   <servlet>
       <servlet-name>ServletRedirector</servlet-name>
       <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
   </servlet> 
   <servlet>
       <servlet-name>ServletTestRunner</servlet-name>
       <servlet-class>org.apache.cactus.server.runner.ServletTestRunner</servlet-class>
   </servlet>

e aggiungendo le seguenti righe dopo l'ultima <servlet>, ovvero subito prima di ogni altro <servlet-mapping>:

   <servlet-mapping>
       <servlet-name>ServletRedirector</servlet-name>
       <url-pattern>/ServletRedirector</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
       <servlet-name>ServletTestRunner</servlet-name>
       <url-pattern>/ServletTestRunner</url-pattern>
   </servlet-mapping>
  • Nel caso si vogliano testare pagine jsp è necessario copiare il file jspRedirector.jsp (contenuto nella cartella /web di struts) all'interno dell'applicazione, preferibilmente insieme alle altre pagine jsp, o comunque in una cartella correttamente inserita nel path dell'applicazione all'interno dell'application server.

Gli errori più comuni che possono insorgere sono tipicamente dovuti, direttamente od indirettamente, ad una errata configurazione del classpath o alla mancata importazione di qualche libreria, quindi è opportuno prestare molta attenzione alla fase di configurazione, per essere certi che in seguito eventuali test falliti dipendano solo dal codice sotto esame e non da qualche libreria mancante.

Lato client

Il client Cactus è una estensione del client JUnit, e ha una struttura sostanzialmente analoga: è una classe in cui ogni metodo rappresenta un test da eseguire, più un metodo main per l'esecuzione dei test stessi.

  • Anche in questo caso è necessario importare, oltre alle stesse librerie del lato server, il file JUnit.jar e le opportune librerie a seconda dei test che si desidera effettuare, o copiare tutta la cartella /lib di Cactus per semplicità (al costo di importare librerie palesemente inutili), senza dimenticare StrutsTestCase, nel caso si vogliano testare elementi di Struts.
  • È necessario creare un file con nome cactus.properties in una cartella inclusa nel path del client. Il contenuto di questo file varia a seconda della configurazione, ma si possono trovare molti esempi in rete o anche nella cartella /examples di Cactus. Nella maggior parte dei casi le impostazioni di default di Cactus sono corrette e non è necessario dare altre indicazioni nel file cactus.properties, ma ci sono tre righe che devono essere presenti in ogni caso:
 cactus.contextURL=http://myServer:myPort/mySite
 cactus.servletRedirectorName=ServletRedirector
 cactus.enableLogging=true

La prima riga indica al client l'indirizzo web dell'applicazione che si vuole testare. Bisogna indicare semplicemente l'URL base dell'applicazione, come se vi si accedesse dal browser. La seconda riga è costante e fa riferimento alle righe aggiunte al file web.xml, e la terza riga indica se abilitare o meno il logging degli errori.

Metatest

Al termine dell'installazione è opportuno effettuare un test dell'installazione stessa, scrivendo un test minimale di sicura riuscita come il seguente:

  public class MyTest extends CactusStrutsTestCase {
       
       public static void main(String[] args) {
               junit.textui.TestRunner.run(MyTest.class);
       }
       
       public void testMinimo() {
               setRequestPathInfo("/login");
               assertNotNull(response);
       }
  }

Questo test semplicemente chiama la pagina di login (eventualmente da sostituire con una pagina qualsiasi presente nell'applicazione) e verifica che venga data una risposta qualsiasi. Se il test non riesce o vengono lanciate delle eccezioni da Cactus è opportuno verificare a fondo l'installazione e i vari path che sono stati configurati, in modo da poter poi procedere con test più impegnativi. È opportuno ricordare che i test possono aver luogo solo ed esclusivamente quando l'application server è attivo e l'applicazione da testare è correttamente configurata sullo stesso.

Esempio di uso

Essendo un framework, l'uso di Cactus è strettamente collegato all'applicazione che si vuole testare. Già l'esempio del paragrafo Metatest, per quanto ridotto, dipende dall'applicazione, perché la pagina di login potrebbe non esistere o avere un nome differente. Quindi per dare un esempio d'uso completo sarà necessario riportare una buona parte di applicazione, di cui verranno man mano evidenziati i punti salienti.

La classe di test

import it.novartis.dbBackEnd.util.AuthenticationRequestProcessor;
import java.io.IOException;
import org.apache.cactus.*;
import junit.framework.*;
import servletunit.struts.CactusStrutsTestCase;

public class SaveCSVActionTest extends CactusStrutsTestCase {
    
    /**
     * Main method. Cambiando awtui con textui si può passare dalla modalità testo a quella grafica.
     * @param args
     */
    public static void main(String[] args) {
        junit.awtui.TestRunner.run(SaveCSVActionTest.class);
    }
    
    /**
     * Default contructor.
     * @param testName
     */
    public SaveCSVActionTest(String testName) {
        super(testName);
    }
     
    /**
     * Parti di codice comuni da eseguire (ogni volta) sul server prima di ogni singolo test.
     */   
    protected void setUp() throws Exception {
        super.setUp();//Assolutamente indispensabile se chiamo setUp().
    }
   
    /**
     * Parti di codice comuni da eseguire dopo ogni test, sul server.
     */   
    protected void tearDown() throws Exception {
        super.tearDown();//Assolutamente indispensabile se chiamo tearDown().
    }

    /**
     * Parti di codice comuni da eseguire (ogni volta) sul client prima di ogni singolo test.
     * In questo caso devo inizializzare la variabile di autenticazione per non essere rimandato alla login.
     */   
    protected void begin() {
        super.begin();
        getSession().setAttribute(AuthenticationRequestProcessor.USER_CONTEXT_KEY, "Ciao");
    }
    
    public void testExportOk() {
        setRequestPathInfo("/saveCSVAction");//La action da chiamare, come è definita in struts.xml
        addRequestParameter("method","export");
        addRequestParameter("fileName","USERTABLE");
        actionPerform();
        try {
            assertNotNull(response.getOutputStream());
        } catch (IOException e) {};//Non c'è redirect quindi non posso testarlo.
        verifyNoActionErrors();
    }
    
    public void testListOk() {
        setRequestPathInfo("/saveCSVAction");//La action da chiamare, come è definita in struts.xml
        addRequestParameter("method","list");
        actionPerform();
        verifyForward("showTableList");
        verifyForwardPath("/jsp/saveCSV.jsp");
        assertEquals("Ciao", this.getSession().getAttribute(AuthenticationRequestProcessor.USER_CONTEXT_KEY));
        verifyNoActionErrors();
    }
}

È necessario importare le classi di Cactus e tutte le classi funzionali allo svolgimento dei test, comprese quelle utili per una eventuale autenticazione sul server. In particolari situazioni, come ad esempio il test di classi che richiedono come parametro o restituiscono altre classi dell'applicazione, questo implica che il client deve avere accesso ad alcune classi dell'applicazione, che dovranno eventualmente essere copiate in locale.

Per un corretto funzionamento del framework è necessario che la classe di test estenda l'apposita superclasse di Cactus relativa alla tipologia di test effettuare: per i test delle pagine jsp la classe di test dovrà estendere JspTestCase, per le servlet dovrà estendere ServletTestCase oppure CactusStrutsTestCase (come nel caso in esame), e così via per tutte le possibilità di test fornite da Cactus o dalle eventuali estensioni.

Il metodo main della classe è strutturalmente identico a quello di JUnit, e questo consente di eseguire con facilità i test Cactus dalle IDE che supportano JUnit. Ad esempio da Eclipse è sufficiente selezionare la classe contenente i test e cliccare "Run as JUnit Test" per far partire l'insieme dei test di quella classe.

Il metodo costruttore si può omettere. Tuttavia, se dovesse essere stato implementato per qualche inizializzazione di carattere generale, è indispensabile eseguire come prima istruzione del metodo, il costruttore della superclasse, che provvede alle inizializzazioni di carattere generale necessarie per sfruttare le librerie lato server di Cactus.

Ogni test che si vuole eseguire deve essere scritto in un metodo il cui nome deve iniziare per test, come quelli dell'esempio. È possibile anche passare dei parametri ai vari test. È fondamentale sottolineare che ogni test è indipendente dagli altri, viene eseguito singolarmente, ovvero tra un test e l'altro l'applicazione viene sempre riportata in uno stato neutro. Di conseguenza per fare test di tipo funzionale, o in generale quando è necessario "attraversare" una serie di pagine od operazioni, si deve scrivere un unico test in cui la risposta ottenuta deve essere elaborata (se necessario) per costruire la richiesta successiva.

Prima e dopo l'esecuzione di ogni test, sul server vengono chiamati, in automatico, i metodi setUp() e tearDown() rispettivamente. Questi metodi sono facoltativi, ma quando vengono dichiarati nella classe di test è sempre necessario chiamare i corrispondenti metodi della superclasse, per garantire una corretta inizializzazione del test. Questi metodi servono per portare l'applicazione in uno stato prestabilito prima di eseguire il test e di riportarla in uno stato neutro alla fine. Allo stesso modo prima e dopo ogni test sul client vengono eseguiti rispettivamente i metodi begin() ed end(), per eseguire eventuali operazioni di configurazione, come ad esempio la creazione dei certificati necessari per l'accesso all'applicazione (cookie, variabili di sessione o quant'altro), e la relativa dismissione al termine dell'esecuzione del test. Nell'esempio infatti è necessario configurare una variabile di sessione per poter accedere alle pagine dell'applicazione, e questa variabile viene appunto inizializzata prima di ogni test per garantire l'accesso. Inoltre è anche possibile definire dei metodi begin###() e end###(), che verranno eseguiti prima e dopo il singolo metodo di test di nome ### (dove ### altro non è che il nome del singolo metodo epurato del prefisso test). Nel nostro esempio si potrebbe creare un metodo beginListOk() per gestire eventuali inizializzazioni accessorie che servono solo per quel test, dividendo quindi le inizializzazioni dal test vero e proprio. È opportuno riportare anche il client in uno stato neutro al termine di ogni test, cancellando eventuali cookie o inizializzazioni particolari che sono state effettuate, per evitare che il risultato dei test possa dipendere dall'ordine di esecuzione. Infatti non ci sono garanzie che i metodi di test vengano chiamati nell'ordine in cui sono nella classe.

Il contenuto dei metodi di test è completamente dipendente dall'applicazione sotto test, quindi è lasciato all'arbitrarietà del programmatore. In linea di principio si indica la pagina o la classe che si vuole testare, si preparano tutti i parametri necessari e si compilano gli eventuali form, dopodiché si chiama la classe o la pagina e si testano i risultati. Le librerie di Cactus danno la possibilità di configurare ogni singolo parametro o proprietà della richiesta http (si può cambiare addirittura l'indirizzo ip del richiedente e la risposta tornerà comunque al client Cactus), e molti metodi per valutare la risposta ricevuta. Il risultato di ogni test è di tipo successo/errore: si ha un successo quando tutte le condizioni vengono soddisfatte, mentre il test fallisce alla prima condizione non verificata, saltando tutte le successive, e viene restituito un prospetto degli elementi che hanno causato il fallimento del test. In questo modo usando i metodi forniti da Cactus si può rapidamente risalire alla condizione che ha generato l'errore.

In linea di principio è sempre bene creare dei test per le risposte corrette e dei casi di test strutturati appositamente per far generare degli errori alla parte da testare, per verificare che la parte da testare risponda "correttamente" alle situazioni d'errore.

Le classi da testare

Per completezza riportiamo qui anche le parti che vengono effettivamente testate dall'esempio precedente, omettendo le parti di configurazione che sono già indicate in SDA_Cactus#Come si installa. Queste parti non sono indispensabili per comprendere il funzionamento di Cactus ma possono essere utili per capire i test di esempio.

La classe SaveCSVAction, riportata qui di seguito, contiene le due action che vengono testate nella classe riportata come esempio:


import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.util.*;
 
public final class SaveCSVAction extends DispatchAction {
   
   /**
    * Per log4j.
    */
   private static Log log = LogFactory.getLog(SaveCSVAction.class);
   
   /**
    * Esporta la tabella indicata in un file csv, senza cambiare la pagina.
    * La pagina viene cambiata solo in caso di errore.
    * 
    * @param mapping The ActionMapping used to select this instance
    * @param actionForm The optional ActionForm bean for this request (if any)
    * @param request The HTTP request we are processing
    * @param response The HTTP response we are creating
    *
    * @exception ServletException if a servlet exception occurs
    */
   public ActionForward export(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
       SaverCSV Salva;//La classe di generazione dello stream.
       
       SaveCSVForm csvForm=(SaveCSVForm) form;//Recupero i dati del form.
       if ((csvForm!=null)&&(csvForm.getFileName()!=null)) {//Per uniformità con il resto del progetto.
           try {
               Salva=new SaverCSV();
               Salva.pingTableCSV(csvForm.getFileName());//Questo PORKAROUND serve per garantire la presenza del messaggio di errore.
               response.setContentType("application/csv; charset=iso-8859-1");//Per configurare il tipo di file da far scaricare.
               response.setHeader("Content-Disposition","attachment;filename=\""+csvForm.getFileName()+".csv\"");//Per generare un file da far scaricare al browser.
               Salva.saveTableCSV(response.getOutputStream(),csvForm.getFileName());//Ho appena collaudato l'esporazione, quindi è piuttosto improbabile che non vada.
               return null;//Non si può fare forward finché non è finito il download! E poi a direil vero la pagina non ha niente da ricaricare.
           } catch (SQLException e) {
               response.reset();//Necessaria per cancellare la predisposizione al download dei file definito poco prima.
               log.error("SaveCSVAction :: SQL exception thrown.");
               ActionErrors errors = new ActionErrors();
               errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("error.CSV.database"));//Visualizzerò questo messaggio di errore.
               saveErrors(request, errors);
               return (mapping.findForward("showTableList"));//Restituisco errore di database.
           } catch (IOException e) {
               response.reset();//Necessaria per cancellare la predisposizione al download dei file definito poco prima
               log.error("SaveCSVAction :: IO ExcelCSV exception thrown.");
               ActionErrors errors = new ActionErrors();
               errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("error.CSV.io"));//Visualizzerò questo messaggio di errore.
               saveErrors(request, errors);
               return (mapping.findForward("showTableList"));//Restituisco errore di i\o.
           }
       } else {//Questo caso particolare lo tratto come un generico errore di i\o. 
           response.reset();//Necessaria per cancellare la predisposizione al download dei file definito poco prima
           log.debug("SaveCSVAction :: Tried access without compiling form.");
           ActionErrors errors = new ActionErrors();
           errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("error.CSV.io"));
           saveErrors(request, errors);
           return (mapping.findForward("showTableList"));//Restituisco errore di i\o.
       }
   }
   
   /**
    * Carica la lista delle tabelle da application.properties e le manda al form per farle visualizzare in jsp.
    * In caso di errore restituisce il generico errore di input.
    */
   public ActionForward list(ActionMapping mapping, ActionForm form,
           HttpServletRequest request, HttpServletResponse response)
   throws Exception {
       
       SaveCSVForm saveForm = (SaveCSVForm) form;//Popolo questo form per creare la lista delle tabelle nella jsp.
       Enumeration lista;
       String temp;//Serve perchè non si può richiamare nextElement più di una volta per ciclo. 
       String[] tables;//Lista dei nomi delle tabelle che sarà stampato nella jsp.
       ArrayList tabNamesList = new ArrayList();
       if (form!=null) {//In questo caso la pagina funzionerebbe lo stesso ma tengo il metodo per uniformità.
           ResourceBundle finder=ResourceBundle.getBundle("application");//Parsing rapido di application.properties!
           lista=finder.getKeys();//Non è efficiente perchè devo parsare tutto il file, ma solo così non rischio di perdere qualche chiave.
           while (lista.hasMoreElements()) {
               temp=lista.nextElement().toString();//nextElement lo posso richiamare una sola volta per dato, quindi devo salvare il dato in una variabile temporanea.
               if (temp.startsWith("saveCSV.export.table_")) {//Intestazione fissa delle chiavi che contengono i nomi delle tabelle. Segue un numero progressivo che viene ignorato.
                   tabNamesList.add(finder.getString(temp));
               };
           };
           tables=new String[tabNamesList.size()];
           tabNamesList.toArray(tables);//Dalla lista creo un array (più comodo) per passarlo al form.
           saveForm.setTableList(tables);
       } else {
           ActionErrors errors = new ActionErrors();
           errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("error.CSV.io"));
           saveErrors(request, errors);
       }
       return mapping.findForward("showTableList");//Alla fine devo comunque tornare alla pagina.
   }
}

Per completezza è opportuno riportare anche un estratto del file struts-config.xml:

       <action path="/saveCSVAction"
            type="it.novartis.dbBackEnd.saveCSV.SaveCSVAction"
            parameter="method"
            name="saveCSVForm">
            <forward name="showTableList" path="/jsp/saveCSV.jsp" />
       </action>

Altri framework di test

Cactus ovviamente non è l'unico strumento opensource di test, ma è uno dei migliori e più flessibili. Tuttavia ci sono molte alternative a seconda della piattaforma su cui si vuole operare e a seconda dei test che si vogliono effettuare. Di seguito sono elencate le principali:

Mock-Object

L'approccio Mock-Object è più generale, complementare a Cactus, e prevede la possibilità di istanziare oggetti incompiuti, ovvero degli stub che possono essere usati per testare alcune parti simulando la presenza delle altre parti necessarie senza curarsi della logica sottostante le parti mancanti. In questo modo è possibile testare arbitrariamente qualunque parte dell'applicazione ed essere certi che gli eventuali errori dipendono solo dalla logica della parte sotto test e non da eventuali problemi che si propagano dalle altre parti chiamate in causa. Nel caso specifico delle applicazioni web è disponibile una versione Mock dell'intera implementazione delle Servlet API: in questo modo si ha la possibilità di dare alle singole pagine che si vogliono testare un ambiente assolutamente arbitrario e di valutarne da vicino la reazione.

Gli svantaggi di questo approccio sono principalmente il fatto che non si sta testando il funzionamento dell'applicazione intera ma solo di una parte di essa avulsa da suo contesto (e questo non esclude certo problemi di integrazione), e il fatto che questi test vengono eseguiti solo in maniera locale, senza passare per l'application server.

JUnit

JUnit è il più noto framework di testing, e sostanzialmente il più generale e flessibile. Ormai tutti i principali strumenti di testing, compreso lo stesso Cactus fanno in qualche modo riferimento a questo framework o ai suoi innumerevoli plugin.

HttpUnit

HttpUnit è un framework per il testing delle applicazioni web, ma è molto più orientato verso gli aspetti relativi alla presentazione e alle interazioni http. HttpUnit è sostanzialmente un insieme di librerie che simulano tutti i aspetti di un browser che interagisce con un server web. Associando queste librerie con JUnit si possono facilmente scrivere test automatizzati per le pagine di una web application. A differenza di Cactus tuttavia questo framework si limita al testing di tutto quello che concerne la presentazione, senza possibilità di intervenire sul server. Esistono svariati framework che si appoggiano su HttpUnit per aggiungere funzionalità. Il più noto di questi è JWebUnit.

Jameleon

Jameleon è un framework di testing usato per automatizzare al massimo il testing degli aspetti di presentazione. Questo framework viene distribuito sotto forma di plugin per altri framework di test molto diffusi, quali ad esempio HttpUnit e JUnit. I test possono essere automatizzati con la massima flessibilità scrivendoli in appositi file xml o leggendo le possibili variabili da file CSV.

Views
Personal tools