DevCorner620

DevCorner: Espresso… what else?

Roberto Orgiu

Abbiamo parlato di Espresso alcune volte sulle nostre pagine, ma un piccolo riassunto può sempre aiutare: si tratta di un framework per il test delle interfacce grafiche basato su jUnit 3 totalmente asincrono, creato e mantenuto da Google, che permette agli sviluppatori di provare automaticamente le proprie app tramite dei check automatici eseguiti sul device. Perché dei test su dispositivo invece dei classici unit che vengono avviati direttamente all’interno dell’IDE? Principalmente è a causa della compilazione dei programmi Android: le API, contenute generalmente nel file android.jar non sono accessibili direttamente dall’ambiente di sviluppo, perché sono conservate all’interno di ogni smartphone e tablet con il robottino a bordo e con il Software Development Kit viene fornito un android.jar che racchiude solamente le firme dei metodi in esso originariamente contenuti, in modo tale che le applicazioni siano compilabili (le firme vengono risolte correttamente, ma Java non fa il controllo sul codice) e, una volta caricata l’app sul dispositivo, le funzioni richiamate in android.jar siano quelle normalmente implementate. In poche parole, su Android Studio non abbiamo tutte le funzioni, ma solamente uno stub, che ci permette di compilare i software senza che Java si lamenti.

LEGGI ANCHE: Espresso 1.1

Vediamo quindi come implementare questo framework tramite Android Studio, iniziando con il creare una semplice app con una TextView il cui testo viene cambiato alla pressione di un bottone: sarà questo il progetto su cui eseguiremo i test. Scarichiamo quindi il jar di Espresso da questo indirizzo e copiamolo nella cartella libs del nostro progetto, come mostrato nella figura sottostante.

StrutturaProgetto

Ora, all’interno di Android Studio, clicchiamo con il pulsante destro sul file jar e selezioniamo la voce Add as library… mentre, all’interno della sezione android.defaultConfig del file build.gradle andremo a specificare che abbiamo bisogno della strumentazione di test tramite l’istruzione

testInstrumentationRunner
"com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"

Nella sezione dependencies dello stesso file andremo invece ad inserire la riga

instrumentTestCompile files('libs/espresso-1.1-bundled.jar')

che spiega a Gradle quali strumenti stiamo utilizzando per i test.

Il progetto è quasi configurato e possiamo iniziare a scrivere del codice nella classe di test per la nostra app: come mostrato nella figura precedente, dobbiamo creare una cartella instrumentTest all’interno del folder src del nostro progetto. All’interno di questo nuovo spazio, ne creeremo un altro denominato java, contenente il package relativo al nostro test: questa struttura è necessaria per permettere ad Android Studio di ignorare i test che abbiamo scritto durante la compilazione della versione di release del nostro software.

Proviamo a creare una classe Java che estenda ActivityInstrumentationTestCase2<MainActivity>, dove MainActivity è l’Activity che vogliamo testare. Vediamo subito il costruttore, nel quale utilizzeremo un metodo deprecato che però ci permetterà di far funzionare Espresso con tutte le versioni di Android che il framework supporta

public TestActivity() {
super("it.androidworld.devcorner.simpletestapp.app", MainActivity.class);
}

Un ultimo passo prima di costruire i test è quello di sovrascrivere la funzione setUp, nella quale avvieremo manualmente l’Activity target, in quanto Espresso non lo farà per noi

public void setUp() throws Exception {
super.setUp();
getActivity();
}

Ora che il progetto è configurato, possiamo iniziare a pensare seriamente ai test: essendo basato su jUnit 3, ogni metodo di test deve iniziare con la parola test, altrimenti non verrà riconosciuto come tale. A titolo esemplificativo, abbiamo creato un piccolo metodo che verifichi che, alla pressione del bottone btnCambiaTesto (che Espresso eseguirà tramite il metodo perform(click())), il testo contenuto nel componente txtCaption venga modificato

public void testFirstClick(){
onView(withId(R.id.btnCambiaTesto)).perform(click());
onView(withId(R.id.txtCaption)).check(matches(withText(R.string.hello_world_2)));
}

Se volete provare questo semplice progetto, fate un salto sul nostro forum, dove troverete tutte le informazioni e le risorse necessarie al completamento di questo tutorial.