Testing software: Testing automatico per Android con Espresso Test Recorder

Testing software: Testing automatico per Android con Espresso Test Recorder

Testing e Casi di test

In informatica, il testing è il processo che esegue il software con lo scopo di scovare malfunzionamenti, il programma viene eseguito con parametri particolari, detti Test Case. La loro progettazione mira a scoprire una classe di errori con il minimo sforzo.
Un primo approccio per la derivazione dei casi di test è dato dal Category Partition Testing, un tipo di test combinatoriale. Esso prevede che le specifiche del sistema vengano strutturate in un insieme di funzionalità testabili separatamente, si individuano i parametri da cui queste dipendono e si stabiliscono dei vincoli per identificare le combinazioni non valide, diminuendo così il numero dei casi di test. Al crescere della complessità e della grandezza del sistema, aumenta anche il numero dei test case e la loro derivazione manuale può diventare lunga, ripetitiva e onerosa.

Tecniche di generazione automatica

La soluzione per ovviare a questi problemi e ridurre tempi e costi legati alla generazione dei casi di test, è la possibilità di derivarli automaticamente tramite l’utilizzo di tecniche apposite; ad esempio analizzando la documentazione di analisi o di progetto, analizzando il codice sorgente, oppure con l’ausilio di un modello del sistema. E’ dunque il caso del Model Based Testing: il modello è una descrizione più semplice del sistema che aiuta a comprenderne il funzionamento. In questo modo è possibile predire il suo comportamento a runtime e le risposte a determinate azioni. Un modello inesatto o approssimativo del sistema può comportare delle previsioni errate, d’altra parte un modello esaustivo spesso è oneroso.
Altre tecniche di generazione automatica dei casi di test prevedono l’interazione con l’applicazione in esecuzione, in maniera sistematica o casuale. In questi ultimi casi si parla di User Session based Testing, una tecnica black box basata sull’analisi di input immessi e output ottenuti durante l’esecuzione dell’applicazione. Ad interagire con l’applicazione sono gli utenti, il cui approccio può variare in base all’esperienza e al loro ruolo: tester interni all’azienda hanno il compito di condurre un’analisi sistematica dell’applicazione per coprire più casi d’uso possibili, mentre utenti esterni potrebbero comportarsi in maniera naturale e utilizzare solo una parte delle funzionalità dell’applicazione, non preoccupandosi delle altre più specifiche che non rientrano nei loro interessi. L’interazione può avvenire in un ambiente controllato, detto Sistema di Capture, che registra le azioni effettuate dall’utente in un log. Successivamente queste vengono tradotte automaticamente in codice eseguibile, ottenendo così un caso di test che può essere rieseguito o essere usato come oracolo per futuri replay. Nella fase di replay il codice ottenuto viene eseguito, e le azioni registrate nella fase precedente vengono replicate in maniera fedele.

Tool Espresso Test Recorder

Testing software: Testing automatico per Android con Espresso Test Recorder

Android Studio offre diversi strumenti a supporto di creazione, studio e testing di applicazioni Android. Precedentemente si utilizzavano estensioni di Eclipse, fin quando Google ha adattato ad Android l’IDE IntelliJ Idea, costruendo il nuovo ambiente di sviluppo integrato (IDE) Android Studio. Esso è disponibile per i sistemi operativi più comuni, tra i quali Windows, Linux e Mac OS X. I tools utili a test di tipo User Session Based sono:

  • AVD Manager: consente di creare emulatori diversi sia per caratteristiche hardware che software. E’ infatti possibile scegliere uno tra più modelli di cellulari o tablet e la versione del sistema operativo. Inizialmente sono proposti solo alcuni dei brand che utilizzano Android, ma è possibile importarne altri. Analogamente per la versione del sistema operativo, è possibile scaricare una API cliccando sulla scritta “Download” presente accanto alle versioni non ancora ottenute. La creazione di una macchina virtuale tramite AVD Manager avviene in tre passaggi.
  • Espresso Test Recorder: è uno strumento di Capture and Replay il cui compito è quello di semplificare il processo di testing generando automaticamente Test Case.

I concetti fondamentali su cui si basa sono le UI interactions e le asserzioni. Le interazioni rappresentano tutte le azioni che una persona potrebbe eseguire utilizzando normalmente l’applicazione; le asserzioni, invece, servono a verificare la presenza di elementi sull’interfaccia ed il loro stato. Espresso permette quindi di interagire con l’applicazione in ambiente controllato e di creare UI tests senza scrivere codice, in particolare: registra tutte le interazioni con gli elementi dell’interfaccia, successivamente genera automaticamente un caso di test che corrisponde alle azioni effettuate. Questo può essere riprodotto per verificare l’esatto funzionamento dell’applicazione.
Per poter utilizzare Espresso in Android Studio occorre cliccare su Run e selezionare la voce Record Espresso Test. Successivamente bisogna scegliere il tipo di device da utilizzare per il test, tra cui le macchine virtuali precedentemente create o eventuali dispositivi reali collegati tramite USB, è possibile creare un nuovo emulatore anche da questa schermata.

Fase di Capture

Una volta selezionato il dispositivo, e terminate le azioni di preparazione necessarie all’avvio dell’applicazione (build del progetto ed installazione della stessa sul dispositivo), comparirà la finestra Record Your Test. Il messaggio “No events recorded yet” viene sostituito dall’elenco delle azioni registrate nel momento in cui esse sono eseguite. Add assertions permette di verificare l’esistenza di determinati elementi dell’interfaccia o il contenuto di essi attraverso delle asserzioni. Espresso crea una vista dell’interfaccia dell’applicazione ed aiuta il tester a riconoscere i vari elementi evidenziandoli con dei riquadri rossi; è possibile selezionarli cliccandoli sulla vista oppure scegliendoli dalla lista del menù Edit Assertion. Il tipo di asserzione varia in base all’elemento selezionato (ad esempio un pulsante può esistere o meno, e quindi l’asserzione sarà Assert Button with ID X exists/does not exist; per le sezioni caratterizzate da testo è inoltre possibile asserire Text is e controllare cosa vi sia scritto, ad esempio per una calcolatrice è possibile asserire Assert Button with ID result text is 10 in seguito ad un operazione 6 + 4). Durante la creazione di un’asserzione, è possibile continuare ad interagire con l’applicazione nonostante la vista sia ancora aperta: le azioni vengono scritte normalmente nel log, ma una volta ultimata l’asserzione, questa verrà posizionata nel punto in cui è stata iniziata, ovvero prima delle interazioni.

Nel codice generato, gli oggetti della GUI coinvolti nel record sono identificati da un ID, spesso anche dal testo con cui vengono mostrati sull’interfaccia, o anche da quali classi derivano (ChildOfPosition). Per riferirsi ad un oggetto di una determinata vista dell’interfaccia si utilizza il metodo onView(), questo ritorna un oggetto ViewInteraction che permette di interagire con la vista. Per indicare da che tipo di attributo esso sia identificato si utilizza il metodo with*(), dove * sta per il tipo di attributo; ad esempio per Id e testo si utilizzano rispettivamente withId() e withText(). Inoltre è possibile specificare se un oggetto sia caratterizzato da più di un attributo, e considerarli tutti con il metodo allOf(). perform() simula le interazioni utente sulla UI, gli argomenti necessari della funzione sono uno o più oggetti ViewAction. La classe ViewAction presenta una lista di metodi relativi alle azioni più comuni, come il click del mouse con click(), scrivere testo in aree apposite con typeText(), cancellare il testo con clearText(), scorrere la vista con scrollTo(). Infine i metodi della classe ViewAssertions sono usati per controllare che l’interfaccia rispetti lo stato desiderato in seguito alle azioni effettuate.

Fase di Replay

Per rieseguire le azioni effettuate in fase di record, è necessario selezionare il caso di test creato automaticamente ed avviarlo su un dispositivo reale oppure su una macchina virtuale preesistente; eventualmente è possibile crearne una al momento dell’avvio. Android studio effettua una build del progetto; nella finestra Run è possibile monitorare l’andamento del test, l’esito ed il tempo impiegato, fino ad arrivare al messaggio “Tests ran to completion” nel momento in cui il test è finito correttamente. Durante il replay le azioni vengono eseguite nello stesso ordine con cui sono state registrate, ma non con le stesse tempistiche.

Pro di Espresso Test Recorder

  • Consente di scrivere casi di test UI automaticamente; in alcuni casi questo approccio è fondamentale, così come anticipato nell’introduzione e poi approfondito nel capitolo 2.
  • Permette la scrittura di test cases in maniera veloce, semplice ed interattiva, non dovendo necessariamente studiare il framework.
  • Permette di registrare sia interazioni che asserzioni, permettendo di controllare lo stato di determinati widget; ciò rende il test più affidabile.
  • Supporta asserzioni multiple.

Contro di Espresso Test Recorder

  • E’ possibile che non siano riconosciuti tutti i widget di una stessa interfaccia, stessa cosa per alcune azioni eseguite su di essi (un esempio è lo scorrimento della barra della percentuale in TippyTipper).
  • Non supporta il recording di WebViews Interactions.
  • Le asserzioni disponibili sono poche e comuni, tra cui: Exists, o dualmente Does not exist, infine Text is per textView e sottoclassi. Nel caso in cui ci fosse bisogno di asserzioni più complicate, esse devono essere introdotte manualmente.
  • Le asserzioni non sono riferibili a determinate notifiche, ad esempio i messaggi di tipo Toast. “Il Toast è la forma di notifica più immediata, si tratta di una piccola finestra rettangolare nera che appare nella parte bassa del display contenente un messaggio con il testo bianco. La sua visibilità dura poco, qualche secondo, e le sue apparizioni improvvise dal basso gli hanno donato questo nome che richiama letteralmente il modo in cui il pane salta fuori dai tostapane”.
  • Nel caso di operazioni asincrone o animazioni, Espresso, non sapendo quanto attendere, aggiungerà delle Thread.sleep() ed il seguente commento “Added a sleep statement to match the app’s execution delay. The recommended way to handle such scenarios is to use Espresso idling resources: https://google.github.io/android-testingsupport-library/docs/espresso/idling-resource/index.html”. Tuttavia questo approccio non risolve il problema, in quanto nel test si resta in attesa di eventi UI e/o network call, quindi operazioni asincrone, e come dice il commento occorre risolvere utilizzando le Idling Resources manualmente.
  • Non ottimizza la dimensione del codice, questo può risultare ridondante; ad esempio: cliccando tre volte il pulsante zero in “TippyTipper”, viene creato tre volte lo stesso oggetto; sarebbe più opportuno invece creare l’oggetto una sola volta e chiamare il metodo quando serve. Ancora, quando il valore della Max UI Depth viene incrementato a favore di quegli oggetti difficilmente identificabili, anche tutti gli altri oggetti verranno caratterizzati da molti attributi, spesso più attributi di quanti servano realmente.
  • E’ possibile che il replay di un caso di test fallisca se eseguito su un dispositivo che abbia impostata una lingua diversa, questo perchè uno dei metodi proposti da Espresso per l’individuazione univoca di un widget è quello di riconoscere in funzione del testo. Tuttavia esso potrebbe cambiare a seconda della lingua, rendendo i test non più funzionanti.
    Per ottimizzare il codice è possibile affiancare alla sua generazione automatica un processo di refactoring. “Il refactoring è una tecnica utilizzata per modificare la struttura interna di porzioni di codice senza modificarne il comportamento esterno”; un processo di questo tipo, quindi, prevede una modifica (sia essa manuale, semiautomatica, o automatica nei casi migiori) che lasci inalterato il comportamento del codice e che porti dei vantaggi, quali ad esempio un miglior utilizzo delle risorse di memoria, migliore leggibilità, complessità minore; o ancora che favorisca la manutenibilità e la riusabilità. Questa potrebbe essere una soluzione anche all’ultimo problema presentato, ricordando che un’ulteriore alternativa è già stata presentata nel capitolo 4: modificando l’impostazione Use Text for element matching è possibile non identificare gli oggetti in base al testo.

Considerazioni sul testing automatico

L’approccio manuale per la generazione di test cases può risultare difficilmente applicabile, in alcuni casi la scelta di effettuare una generazione automatica risulta quasi obbligata. Gli sviluppatori, tuttavia, non sempre sono orientati ad effettuare UI Tests automatici per le proprie applicazioni, spesso per mancanza di tempo: bisognerebbe infatti capire il nuovo framework su cui si lavora. Espresso Test Recorder semplifica notevolmente il processo di testing e non richiede una conoscenza a priori nel padroneggiare le sue funzionalità: è un framework che permette di effettuare UI Tests in modo semplice, interattivo e veloce, dimostrandosi quindi intuitivo. E’ gratuito ed offerto dallo stesso ambiente utilizzabile per lo sviluppo delle applicazioni; qui viene affiancato da un secondo tool altrettanto utile, AVD Manager, che consente di effettuare i record su più dispositivi virtuali, variabili sia per dispositivo che per versione del sistema operativo.
Le caratteristiche citate rendono questo strumento di Capture and Replay adatto agli sviluppatori alle prime armi. I tester, che hanno acquisito più dimestichezza, hanno la possibilità di personalizzare la precisione dei casi di test modificando le impostazioni Data collection and code generation settings. Ad ogni modo, queste hanno dei valori di default che risultano abbastanza equilibrati e predisposti per la maggior parte delle situazioni. Al momento il tool presenta dei piccoli difetti; alcuni di essi risolvibili con determinate accortenze, altri no. Ci si può aspettare un miglioramento di queste funzionalità con futuri aggiornamenti di AndroidStudio.

Pubblicato da Vito Lavecchia

Lavecchia Vito Ingegnere Informatico (Politecnico di Bari) Email: [email protected] Sito Web: https://vitolavecchia.altervista.org

Lascia un commento

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