• Come un abito cucito su misura, i nostri progetti software uniscono le potenzialità di tecnologie innovative alle specifiche esigenze del cliente.

    Showcase progetti
  • Analizziamo e razionalizziamo con il cliente i processi e le attività della propria azienda, per poi seguirlo nella scelta delle giuste strategie IT da adottare.

    Le nostre competenze
  • Crediamo nelle potenzialità di un percorso formativo che unisca forti basi teoriche e metodologiche ad una continua applicazione pratica di quanto si apprende.

    Dettaglio dei corsi
  • Progettiamo e sviluppiamo sistemi e progetti basati su dispositivi mobile consumer (iPhone, Windows Phone 7 Series), industriali (Windows CE) e custom (basati su microcontrollori 8/16/32 bit).

    Approfondimenti
 

Test della UI di una applicazione con Selenium

September 4, 2009 15:17 by F.Bernabei

Al giorno d’oggi predisporre dei test automatici sulle applicazioni che sviluppiamo è divenuto un requisito fondamentale per vari motivi. Primo fra tutti per evitare che a seguito di modifiche al software (per introdurre nuove funzionalità o correzione di bug) si possa in modo automatico, verificare che tutte le funzionalità precedenti (o meglio tutte quelle precedentemente messe sotto test e verificate) continuino a funzionare in modo corretto e che non si siano quindi introdotti ulteriori bug con le modifiche apportate (questi sono detti test di [non] regressione).

In questo articolo parleremo in particolare di test automatizzati dell’interfaccia utente, argomento che ho già introdotto in un mio post precedente pubblicato su DotNetUmbria.org a cui si può far riferimento per un’introduzione di base.
A differenza degli unit test, l’automatizzazione della UI permette di fare controlli ad un “livello più alto” ed integrato, utile per testare in modo ripetitivo un intero caso d’uso della nostra applicazione o aggiungere un set di test completo ad applicazioni già esistenti.
Come illustrato nell’articolo introduttivo appena menzionato, esistono vari framework per raggiungere il nostro scopo  e sicuramente due dei più utilizzati sono WatIn e SelniumHQ (di cui parleremo in modo approfondito nel prosegui dell’articolo). Si tratta di framework che permettono il test di applicazioni WEB come vedremo in seguito, ma va segnalato che esistono soluzioni analoghe anche per il test di applicazioni Windows, come l’ottima Microsoft UI Automation  per il test di applicazioni Windows Presentation Foundation che magari potrebbe essere argomento per un articolo futuro.

Ma torniamo allo scopo principale di questo post, ossia vedere un esempio concreto di implementazione di un test di un’applicazione reale implementato mediante l’uso di Selenium. Come caso d’uso per provare le funzionalità di base del framework ho scritto una piccola applicazione ASP.NET che banalmente permette di inserire del testo in una casella di testo ed alla pressione di un bottone riporta il testo inserito in una etichetta. Il risultato finale in esecuzione è visibile nell’immagine seguente ed il codice è scaricabile direttamente dal link presente al termine dell’articolo.

uitestwebapp

Come si evince dall’immagine in realtà ci sono due bottoni che eseguono l’operazione appena descritta. Questo per poter provare diversi approcci di test in quanto in un caso l’aggiornamento dell’etichetta viene fatto con codice lato server ed il bottone esegue quindi un postback (all’interno di un UpdatePanel Ajax) e nel codice C# della pagina viene aggiornato il testo.
Nel secondo caso invece il lavoro viene eseguito completamente lato client con del codice Javascript, facendo uso anche del comando alert per visualizzare una finestra di messaggio in modo da vedere come interagire con questo elemento in fase di test.

Eccoci ora arrivati all’implementazione vera e propria dei test. Come anticipato in questo caso utilizzeremo SeleniumHQ che mette a disposizioni diversi strumenti per raggiungere il nostro scopo tra cui i principali sono:

Selenium IDE: Un ambiente integrato distribuito come plug-in per FireFox per la creazione rapida di test e suite di test. I test creati possono essere salvati in diversi formati ed editati direttamente dall’IDE ed essere rieseguiti in qualsiasi momento.

Selenium Remote Control (RC): Un insieme di librerie e tools per scrivere e pilotare i test direttamente da codice. Fornisce un insieme di librerie utilizzabili da svariati linguaggi di programmazione (C#, Java, PHP, Ruby e altri) e permette di eseguire i test praticamente su tutti i browser più diffusi.

Selenium Grid: Un sistema per “espandere” Selenium RC e consentire l’esecuzione dei test in parallelo su server multipli.

Partiamo con Selenium IDE in modo da poter subito prendere contatto con le possibilità offerte dal framework. Dopo averlo scaricato ed installato lo troveremo in FireFox nel menu “Tools –> Selenium IDE” e da qui possiamo lanciarlo. SeleniumIDE

Una volta aperto, l’IDE si presenterà più o meno come in figura e già in modalità di registrazione attiva (identificabile dal bottone con “pallino rosso” premuto nella parte destra della toolbar in alto), il che significa che ogni azione che noi faremo nel browser da cui lo abbiamo aperto, verrà registrata nello script corrente e potrà essere riprodotta in modo automatico rieseguendo il test in seguito. Non ci resta che inserire nella barra degli indirizzi di FireFox l’URL a cui raggiungere l’applicazione (nel nostro caso http://localhost:53771/ visto che stiamo effettuando il test di una applicazione in esecuzione in Visuall lStudio e che gira quindi su una porta creata dinamicamente del Web Development Server), premere invio per avviare la navigazione ed eseguire tutte le azioni che devono essere registrate per essere poi ripetute in seguito. Per esempio i seguenti passi:

  1. Scrivere qualcosa nella casella di testo (nell’esempio ho inserito “Bernabei”)
  2. Premere sul bottone con etichetta “Saluta via javascript”
  3. Premere OK sull’alert che appare
  4. Verificare che sull’etichetta appaia il testo “Ciao Bernabei!”

Quest’ultimo punto ovviamente non corrisponde ad un’interazione che facciamo con il browser, quindi dobbiamo “spiegare” a Selenium come farlo e questo si traduce banalmente nel premere il tasto destro del mouse sull’etichetta che vogliamo controllare. Nel menu contestuale di FireFox appariranno anche tutte le azioni che Selenium può “eseguire” su quel determinato elemento, fra le quali quella che ci verifyTextPresentinteressa che è “verifyTextPresent”. Selezionando il comando viene aggiunto nello script correntemente in registrazione l’istruzione richiesta che effettua il controllo specificato al passo numero 4.

Ora lo script è pronto per essere salvato per rieseguirlo in futuro (per farlo basta caricarlo nell’IDE e premere l’apposito pulsante “Play” della toolbar) o editato manualmente all’interno dell’ambiente. In quest’ultimo caso è possibile farlo aggiungendo i comandi alla lista visualizzata, specificando appunto il comando da eseguire selezionabile da una lista molto ampia di azioni possibili (il set di comandi disponibili è chiamato “selenese”), il target ossia l’elemento della pagina a cui il comando si riferisce ed il valore se necessario per il comando specifico. Alternativamente si può modificare lo script agendo direttamente sul “sorgente” accessibile selezionando il tab “Source” dell’IDE e modificando manualmente i comandi che verranno eseguiti dallo script (questa modalità ovviamente richiede la conoscenza dei comandi messi a disposizione dal framework in quanto non è presente un qualcosa tipo IntelliSense che può aiutare a compilare lo script.

Prima di concludere vale la pena dare uno sguardo al sorgente dello script che per default viene rappresentato usando una sintassi HTML. In pratica si tratta di un HTML contenente un tag TABLE in cui ogni riga TR corrisponde ad un comando da eseguire e contiene tre celle TD che rappresentano comando, target e valore.

Lo script appena creato viene rappresentato in HTML nel modo seguente:

   1: <?xml version="1.0" encoding="UTF-8"?>
   2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
   3:  
   4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   5: <head profile="http://selenium-ide.openqa.org/profiles/test-case">
   6:     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
   7:     <link rel="selenium.base" href="http://localhost:53771/" />
   8:     <title>New Test</title>
   9: </head>
  10:  
  11: <body>
  12: <table cellpadding="1" cellspacing="1" border="1">
  13:     <thead>
  14:         <tr><td rowspan="1" colspan="3">New Test</td></tr>
  15:     </thead>
  16:     <tbody>
  17:         <tr>
  18:             <td>open</td>
  19:             <td>/</td>
  20:             <td></td>
  21:         </tr>
  22:         <tr>
  23:             <td>type</td>
  24:             <td>txtNome</td>
  25:             <td>Bernabei</td>
  26:         </tr>
  27:         <tr>
  28:             <td>click</td>
  29:             <td>//input[@value='Saluta via javascript']</td>
  30:             <td></td>
  31:         </tr>
  32:         <tr>
  33:             <td>assertAlert</td>
  34:             <td>Stai per essere salutato...</td>
  35:             <td></td>
  36:         </tr>
  37:         <tr>
  38:             <td>verifyTextPresent</td>
  39:             <td>Ciao Bernabei!</td>
  40:             <td></td>
  41:         </tr>
  42:     </tbody>
  43: </table>
  44: </body>
  45: </html>

Dallo stesso IDE è possibile visualizzare lo script in un altro formato riutilizzabile poi da Selenium RC per eseguire il test direttamente da codice. Ad esempio scegliendo il formato C# la rappresentazione dello stesso script è la seguente:

   1: using System;
   2: using System.Text;
   3: using System.Text.RegularExpressions;
   4: using System.Threading;
   5: using NUnit.Framework;
   6: using Selenium;
   7:  
   8: namespace SeleniumTests
   9: {
  10:     [TestFixture]
  11:     public class Untitled
  12:     {
  13:         private ISelenium selenium;
  14:         private StringBuilder verificationErrors;
  15:         
  16:         [SetUp]
  17:         public void SetupTest()
  18:         {
  19:             selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://localhost:53771/");
  20:             selenium.Start();
  21:             verificationErrors = new StringBuilder();
  22:         }
  23:         
  24:         [TearDown]
  25:         public void TeardownTest()
  26:         {
  27:             try
  28:             {
  29:                 selenium.Stop();
  30:             }
  31:             catch (Exception)
  32:             {
  33:                 // Ignore errors if unable to close the browser
  34:             }
  35:             Assert.AreEqual("", verificationErrors.ToString());
  36:         }
  37:         
  38:         [Test]
  39:         public void TheUntitledTest()
  40:         {
  41:             selenium.Open("/");
  42:             selenium.Type("txtNome", "Bernabei");
  43:             selenium.Click("//input[@value='Saluta via javascript']");
  44:             Assert.AreEqual("Stai per essere salutato...", selenium.GetAlert());
  45:             try
  46:             {
  47:                 Assert.IsTrue(selenium.IsTextPresent("Ciao Bernabei!"));
  48:             }
  49:             catch (AssertionException e)
  50:             {
  51:                 verificationErrors.Append(e.Message);
  52:             }
  53:         }
  54:     }
  55: }

Da notare che se l’IDE viene impostato per rappresentare lo script nei formati per Selenium RC non sarà più possibile utilizzare la visualizzazione di default dell’IDE stesso, quella in formato tabellare che permette di aggiungere comandi selezionandoli da una ComboBox.

L’utilizzo dell’IDE consente dunque di creare in modo rapido delle suite di test (è possibile caricare più script alla volta nell’IDE ed eseguirli tutti in una volta) da rieseguire all’occorrenza per verificare il comportamento della UI. Se questo non fosse sufficiente, o se si volesse organizzare un test per controllare il funzionamento dell’applicazione su più di un browser anche diverso da FireFox, basterà utilizzare le API messe a disposizione dal Remote Control per personalizzare in modo estremamente capillare il comportamento del test.

In allegato a questo articolo è possibile scaricare i sorgenti del progetto WEB di test utilizzato e due script che “utilizzano” in modo diverso l’applicazione testandone una volta il comportamento implementato con il postback asincrono e l’altra come nell’esempio descritto in precedenza che fa uso di javascript.

Buon test a tutti Winking!

 

File allegati:

 


Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Proposta per argomenti da trattare nelle giornate di autoformazione Innovactive

July 8, 2009 14:42 by L.Maiorfi

Abbiamo pensato di svolgere delle giornate di formazione interna per condividere le conoscenze che membri di team diversi all'interno di InnovActive hanno acquisito nello sviluppo dei progetti assegnati.

Facciamo qui sul sito un primo round di proposte che poi verranno valutate e andranno a far parte della scaletta dell'incontro (o degli incontri).

Comincio da quello che ho visto io e che ritengo utile per tutti:

1) ADO.NET Entity Framework.  Avendo sviluppato un progetto piuttosto complesso con questo tool di accesso ai dati, ho cominciato a conoscerne i punti di forza e di debolezza, le modalità di utilizzo più o meno performanti e ho un'idea di quando potrebbe essere utilizzato con profitto dal team.

2) Jquery:  L'utilizzo di un framework di sviluppo javascript è ormai contitio sine qua non per sviluppare con efficienza applicazioni web responsive. Jquery è un framework che ha dalla sua molte caratteristiche che ne fanno un ottimo candidato per l'utilizzo da parte di InnovActive: può essere utilizzato anche solo come strumento di facilitazione della navigazione/manipolazione del DOM oppure sfruttato a livelli ben più complessi: questo ne fa un tool che aumenta la produttività da subito. Ha un'infinità di plugin di ottima fattura che si possono utilizzare tal quali, ha un'infrastruttura ufficiale, ui.jquery.com, che fornisce gadget di base stabili e potenti, è l'infrastruttura JS più utilizzata sul web e non ultimo è l'infrastruttura JS scelta da Microsoft (per esempio su MVC) ed è quella che meglio si lega al ciclo di pagina asp.net

3) ELMAH:  un tool estremamente semplice e versatile per il logging e la gestione degli errori su ASP.NET

4) Log4Net:  potentissima e versatilissima libreria per il logging, mi ha salvato innumerevoli volte. dovrebbe essere insegnata alle scuole elementari insieme alla manovra di heimlich.

 

per quanto riguarda i desiderata, mi piacerebbe saperne di più sulle potenzialità di TFS, tanto per cominciare.


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5