Testare applicazioni web con Selenium e Hudson

La fase di test di una applicazione è una di quelle più delicate in quanto dovrebbe cominciare (almeno il design) non appena i requisiti funzionali di una applicazione sono definiti. E’ difficile perchè entrano in gioco diversi fattori dall’usabilità di una applicazione all’architettura della applicazione stessa.

Normalmente in applicazioni Java avete Junit (o TestNG o ancora Nunit per applicazioni .NET) come libreria che vi permette di creare unit test per la vostra applicazione. In questa maniera avete modo di verificare che le vostre classi fanno il loro dovere. Per rendere poi gli unit test automatici potete usare continuous integration server come Hudson i quali non appena compilano il vostro codice permettono anche di eseguirli.

Se però sviluppate una applicazione con interfaccia web vi servirebbe uno strumento che vi permette di simulare il comportamento di un utente (cosa alquanto difficile) o comunque che dimostri che i requisiti funzionali dell’applicazione siano rispettati. Si parla di requisiti come:

  • se l’utente si vuole loggare sul sito web:
    • egli clicca sul link per accedere sulla pagina di login
    • digita username e password
    • clicca sul pulsante di login
    • appare una stringa dove esce il nome utente o comuque una pagina di benvenuto
    • l’attesa tra la pressione del pulsante login e il caricamento della pagina di benvenuto non deve essere più di tot secondi
  • se l’utente vuole cercare una risorsa nel sito web:
    • egli digita una parola chiave nell’apposito form
    • clicca sul pulsante cerca
    • visualizza, se esistono, pagine che contengono quella parola chiave

Rimane ovvio che il requisito del login più restringente è quello sul tempo di attesa, esso dovrebbe dipendere dall’achitettura software (accesso al database, uso di cookie ecc), mentre sulla ricerca non è sempre vero che inserendo una parola chiave riusciamo a trovare qualcosa.

Selenium è un software scritto per testare interfacce web che di base si presenta come una estensione per Firefox (Selenium IDE) o ancora come server (Selenium RC) per automatizzare i test e lanciare istanze di browser per eseguire i test stessi.

Selenium IDE in pratica permette di scrivere test tramite una comoda interfaccia web. Questi test in realtà vengono salvati come pagine html che contengono una semplice tabella come la seguente:

New Test
open /ig?hl=it
type q selenium
clickAndWait btnG
verifyTextPresent Selenium web application testing system
clickAndWait link=Selenium web application testing system
clickAndWait link=Documentation
clickAndWait link=Selenium-IDE

Questo test in particolare esegue la ricerca su http://www.google.it della parola “selenium”, verifica che tra i risultati compare la scritta “Selenium web application testing system”, clicca sul link e accede alla sezione documentazione sul Selenium-IDE. I comandi (scritti in Selenese :-) ) sono di semplice comprensione (accettano da 1 a 2 parametri) e possono essere generati automaticamente dal Selenium IDE utilizzando la modalità Record che registra l’attività utente sul sito web e modificati manualmente in ogni momento. Esistono diversi comandi che permettono per esempio:

  • di simulare il doppio click
  • di simulare la pressione di un tasto
  • di simulare il mouse sopra un particolare oggetto (evento OnMouseOver)
  • di fermare l’esecuzione del test per un determinato tempo
  • di rimuovere i cookie
  • di catturare lo screenshot di una pagina
  • di salvare e caricare variabili
  • ecc

Capite bene però che, leggendo il test precedente, il test può fallire per diversi motivi (il link documentazione è stato cambitato ad esempio) e non esistono condizioni per dire “se questa condizione fallisce allora verifica quest’altra”. Inoltre si vorrebbe verificare se gli stessi test sono validi su diversi browser e magari rendere la procedura più automatica possibile.

Ecco per cui è stato realizzato Selenium RC, un server java che rimane in ascolto di chiamate da client scritti in diversi linguaggi (Java, C#, Perl, PHP, Python, Ruby) ed esegue i test lanciando istanze di browser come Firefox, Internet Explorer, Safari e Opera.

Un esempio di test in Java sarebbe:

package com.example.tests;

import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

public class NewTest extends SeleneseTestCase {
    public void setUp() throws Exception {
        setUp("http://www.google.com/", "*firefox");
    }
      public void testNew() throws Exception {
          selenium.open("/");
          selenium.type("q", "selenium");
          selenium.click("btnG");
          selenium.waitForPageToLoad("30000");
          assertTrue(selenium.isTextPresent("Results * for selenium"));
    }
}

Il codice è anche qui di facile comprensione, occorre leggersi con comodo le API da usare. Quindi magari ora potreste pensare di includere il codice in Junit o Nunit test per esempio da essere eseguiti automaticamente da un continuous integration server.

Hudson in particolare ha 2 plugin di cui uno apposito per Selenium RC e permette di generare i report, alternativamente esiste un Ant task. La cosa interessante è che partono direttamente dall’html senza passare ai test scritti in Java (a voi la scelta).

Il problema concreto è quindi non tanto usare i comandi quanto identificare l’oggetto su cui eseguire il comando, infatti potete usare attributi Id, attributi Name, DOM, Xpath, CSS sta a voi vedere dove usare una tecnica o l’altra perchè per esempio in talune applicazioni gli attributi Id sono generati dinamicamente e non potete di conseguenza creare i test.

Sul sito di Selenium trovate molta documentazione dallo screencast, al forum, bug tracker e al wiki.

Sul sito di Refcardz trovate una scheda riassuntiva.

Qualche nota interessante:

Buon test e buon anno a tutti !

Advertisements

Junit e SoapUI, strumenti per testare web services

In genere durante il processo di sviluppo di una applicazione una delle fasi sottovalutate è quella di testing.

La fase testing dovrebbe in teoria iniziare non appena i requisiti della applicazione sono stati definiti e dovrebbe poi continuare per il tutto il processo di sviluppo poichè all’aumentare della complessità della applicazione i test devono garantirne il suo funzionamento e, dunque, esistono diversi livelli di test da quelli di unità a quelli di sistema e validazione (acceptance test).

Indipendentemente dai livelli esistono test di varia natura da quelli funzionali a quelli di robustezza e performance. In sostanza come avete potuto capire il tutto puo’ richiedere abbastanza tempo e quindi se si cerca di rendere quanto più automatica questa fase è meglio.

Nel mondo Java il tutto inizia con le librerie di Junit. Rilasciate con licenza Common Public Licence 1.0 sono arrivate, al momento in cui scrivo, alla versione 4.5 (del 8/8/2008). Esse permettono di automatizzare la fase di testing scrivendo metodi che contengono alcune chiamate alle librerie e tra queste esistono i metodi “assertEquals()” che verificano che 2 oggetti (quello atteso e quello di cui si dispone) sono uguali (da cui poi tuttte le derivazioni come il confronto tra booleani, stringhe ecc.).

Nonostante siamo alla versione 4.x la serie precedente, 3.x, viene mantenuta questo perchè le classi che contengono i metodi devono essere opportunamente scritte, in particolare con la 3.x ad esempio i nomi dei metodi devono avere una certa struttura (testXXX, cioè devono iniziare per test) mentre la 4.x permette di avere una certa elasticità usando pero’ le annotazioni come javadoc. Eclipse 3.4 annovera tra le sue librerie sia Junit 3 (3.8.2) e Junit 4 (4.3.1) e permette di creare Test case usando l’una o l’altra libreria. In questo esempio vedere come creare Junit Test case con la versione 4.

Un’ultima cosa che dovete sapere su Junit è che potete raggruppare i Test case in Test suite che eseguono più test. Inoltre quando si scrivono metodi per i test può capitare che questi condividano degli oggetti inizializzati; Junit permette di inizializzare, e poi distruggere, risorse condivise tramite i metodi setUp() e tearDown(), vi lascio poi scoprire il tutto facendovi spulciare la documentazione.

Ant, non solo vi permette di automatizzare il tutto con il suo Junit task, ma vi crea anche, a partire dai risultati di ogni test, dei sempli report.

Quando create dei web services usando il plugin di Axis2, Codegen Wizard, per Eclipse probabilmente avrete notato l’opzione che genera anche i test cases che alla fine non sono altro che semplici client che dovete inizializzare dando l’end point da contattare e costruendo gli oggetti che da passare allo stub. Inoltre potete modificare il file Ant generato per generare i report che vi avevo accennato prima.

Junit è pero’ la punta di un iceberg. Difatti si sono evolute applicazioni che si occupano solo della fase di testing come Cactus, Fitnesse (che è un wiki che fa acceptance test) , Selenium che allargano l’orizzonte anche alle applicazioni web, lo stesso Spring tra l’altro contiene un modulo per il testing. Se poi parliamo di performance esiste jMeter (a cui SOAPUI fa concorrenza).

SoapUI è una applicazione rivolta ai web services che abbiamo già incontrato quando vi ho accennatto alla possibilità di validare i file wsdl per migliorare l’interoperabilità.

Una delle funzionalità carine è quella di creare al volo una richiesta SOAP automaticatimente generata a partire dal file wsdl, generando poi report e test di copertura su file wsdl.

Junit non è poi l’unico testing framework esistono TestNG ed anche Nunit (che è il porting di Junit per .NET) e una miriade di applicazioni che vengono usate per testare i vari linguaggi.

A questo punto vi auguro buona esplorazione in questo mondo che, anche per me, si sta rivelando sempre più grande e al tempo stesso affascinante (soprattutto come sviluppatore pigro che vorrebbe automatizzare tutto ciò :-) ).

P.S: Occorre dire che lo stesso Eclipse nel suo piccolo permette di testare on-line il servizio web. Difatti cliccando con il tasto destro del mouse sul file wsdl dovreste ritrovarvi nel menu contestuale la voce Web Services da cui la sotto voce Test with Web Services Explorer che è una interfaccia web che vi permette di compilare i campi  da mandare nella richiesta SOAP e subito sotto vedere la risposta.

Link interessante: http://wso2.org/library/3862

Alla prossima