Android Testing: Espresso Test Recorder

I motivi per cui realizzare dei test automatizzati per una applicazione possono essere diversi. Generalmente nelle applicazioni software vengono realizzati al fine di:

  • validazione del funzionamento
  • non regressione

In Android, oltre a queste motivazioni, è da considerare che un’applicazione viene eseguita su dispositivi con diverse caratteristiche hardware: dimensione e risoluzione dello schermo, memoria ram disponibile, connettività, potenza della cpu, ciò comporta che è quasi impossibile effettuare dei test manuali e quindi è necessario realizzare dei test automatizzati.

In Android i test sono basati su JUnit, e vengono suddivisi in due macro-categorie:

  • local unit tests eseguiti sulla JVM local i quali non hanno accesso a funzionalità dell’android framework
  • instrumented tests eseguiti sui dispositivi android (fisici o emulatore).

Essenzialmente questa suddivisione serve solo per distinguere quei test che vengono eseguiti sulla JVM locale, dai test eseguiti sulla piattaforma Android. Infatti quando si realizzano i test in Android Studio, per ogni modulo del progetto, vengono previste due directory una per i test Local unit module-name/src/test/java/e l’altra per i test Instrumented tests module-name/src/androidTest/java/.

Però la classificazione reale da tenere in considerazione quando si vuole realizzare una completa suite di test è la seguente:

Android Testing Support Library

Per effettuare i test, Android mette a disposizione Android Testing Support Library la quale fornisce un insieme di API per permettere di costruire ed eseguire dei test. La libreria include le seguenti APIs instrumentation-based, che sono utili quando si vuole automatizzare i test:

  • AndroidJUnitRunner JUnit 4 test runner per Android.
  • Espresso framework per UI test, adatto per test funzionali in-app.
  • UI Automator framework per UI test, adatto per test funzionali cross-app di sistema o installate.

In questo articolo ci concentreremo sui test di integrazione(o funzionali) di componenti all’interno dell’app e quindi verrà utilizzato il framework Espresso.
Un test di integrazione è per definizione: il processo di verifica dell’interazione tra componenti software, volto a verificare che il software svolga effettivamente il suo scopo.


Espresso Test Recorder

Uno dei problemi principali nel creare una suite di test è quella di dover imparare un nuovo framework. Spesso gli sviluppatori evitano di creare dei test automatizzati per questo motivo (quindi per mancanza di tempo).

A partire da Android Studio 2.3, c’è a disposizione un tool chiamato Espresso Test Recorder per semplificare il processo di testing, ed è stato introdotto proprio per il motivo di cui sopra.
Esso si basa sul framework Espresso e permette di aggiungere UI test, in app esistenti, in maniera semplice e interattiva.

Per avviare tale tool basterà andare sul menu run -> Record Espresso Test

L’anatomia di un test UI, e quindi anche dei test con il framework espresso consiste in:

  1. trovare una view
  2. eseguire un’azione
  3. controllare il risultato

l’interazione(1 e 2) equivale ad un tap e altri tipi di azioni che un utente potrebbe realizzare interagendo con l’app, mentre il controllo serve a verificare l’esistenza di un elemento visuale sullo schermo. 
Ad esempio si potrebbe pensare ad un TextInputLayout e quindi controllare se viene visualizzato il messaggio di errore a fronte di un input errato.

Per utilizzare il tool, occorre mettere ad off tutte le animazioni sul device di test, perchè potrebbero causare risultati inattesi e potrebbero far fallire il test. Per farlo basta andare in Settings>>Developer options e mettere su off:

  • Window animation scale
  • Transition animation scale
  • Animator duration scale

Il tool risulta molto semplice ma essendo ancora in fase sperimentale ha diverse limitazioni:

  • numero limitato di assertion: è possibile solo verificare se una View esiste o non esiste, e nel caso delle TextView e sottoclassi anche il “text is”. In caso siano necessarie le altre occorre modificare il codice generato.
  • non supporto per le IdlingResources, quindi nel caso di animazioni o operazioni asincrone, occorre gestirle manualmente, perchè Espresso Test Recorder non sa quanto attendere e quindi il test fallirà per via di View non conosciuta.
  • non supporto per onData delle adapterView.
  • non supporta per le interazione UI che sono al di fuori del codice dell’applicazione.

Di queste, a mio parere quella cruciale è il non supporto delle IdlingResources. Il tool proverà a risolvere il problema aggiungendo delle Thread.sleep() e 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-testing-support-library/docs/espresso/idling-resource/index.html

Ma 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 usando le IdlingResources manualmente.

Conclusioni

Espresso Test Recorder è un ottimo tool per iniziare ad utilizzare e imparare a scrivere test con il framework Espresso, proprio perchè non richiede conoscenze a priori ed è estremamente rapido generare delle classi di test registrando le interazioni attraverso il device rispetto a scrivere codice.

Ovviamente le limitazioni presenti attualmente vanno ad incidere sul mio parere finale, però penso che lo consiglierei appunto per introdursi nel mondo del testing.

riferimenti: https://developer.android.com/training/testing/start/index.html

https://codelabs.developers.google.com/codelabs/android-testing/index.html