Come accennato nella lezione precedente, possiamo prevedere l'uso di unit test su un nuovo progetto di Android Studio come segue:
dependencies {
...
testCompile 'junit:junit:4.12'
...
}
La classe predisposta per i test unitari sarà simile alla seguente (il cui contenuto ha qui carattere esemplificativo):
public class ExampleUnitTest {
@Test
public void addition_test() throws Exception {
assertEquals(4, 2+2);
}
}
Si tratta di una classe Java, il cui unico metodo ha due caratteristiche particolari:
- l'annotazione
@Test
, messa a disposizione da JUnit per indicare che quel metodo rappresenta un test (possiamo usare tale annotazione in quanto abbiamo incluso JUnit4: fino alla versione 3, invece, i metodi di questo genere avevano un nome con prefisso "test"); - il metodo
assertEquals
Per eseguire il test, su Android Studio dovremo agire tramite menu:
Al termine dell'esecuzione, Android Studio mostrerà il risultato.

Dall'immagine qui riportata, emerge che il test è stato eseguito su Java Virtual Machine, è durato 2 ms ed è stato portato a termine correttamente: tra l'altro, il successo del collaudo ci viene visivamente confermato anche dal colore verde della banda. Inseriamo ora un test destinato a fallire, aggiungendo il metodo seguuente:
@Test
public void test_boolean() throws Exception {
assertTrue(false);
}
Usiamo un'altra delle assertion di JUnit, ovvero assertTrue
, che verifica se il valore passato corrisponde al true
false
Ci viene segnalato che due test sono stati eseguiti ed uno è fallito. Anche i colori associati ai singoli test hanno un significato particolare:
- verde
- giallo
- rosso
Unit test in un progetto Android
Supponiamo di avere un'app in cui l'interfaccia grafica permetta di registrare dati personali di individui. Per ognuno di essi, vengono raccolti una serie di informazioni - nome, cognome, età e se è automunito - e salvati in oggetti appartenenti alla classe Persona, definita come segue:
public class Persona {
private String nome;
private String cognome;
private int eta;
private boolean automunito;
// OMISSIS: metodi getter e setter
}
Tramite il form dell'interfaccia grafica, creiamo degli oggetti Persona
e li inseriamo nella classe DataManager
, che li custodisce in un ArrayList
in maniera non persistente:
public class DataManager {
private ArrayList elenco=null;
void nuovoInserimento(Persona nuovo)
{
elenco.add(nuovo);
}
int numeroInserimenti()
{
return elenco.size();
}
void cancellaPersona(int pos)
{
if (numeroInserimenti()>0 && pos<elenco.size())
elenco.remove(pos);
}
}
Il funzionamento dell'app è fortemente legato a quello di DataManager
ExampleUnitTest
test_inserimento
DataManager
test_cancellazione
public class ExampleUnitTest {
@Test
public void test_inserimento() throws Exception {
DataManager dm = new DataManager();
dm.nuovoInserimento(new Persona("Giulio", "Rossi", 34, true));
dm.nuovoInserimento(new Persona("Paolo", "Verdi", 25, false));
dm.nuovoInserimento(new Persona("Silvio", "Bianchi", 63, true));
assertEquals(3, dm.numeroInserimenti());
}
@Test
public void test_cancellazione() throws Exception {
DataManager dm = new DataManager();
dm.nuovoInserimento(new Persona("Giulio", "Rossi", 34, true));
dm.nuovoInserimento(new Persona("Paolo", "Verdi", 25, false));
dm.nuovoInserimento(new Persona("Silvio", "Bianchi", 63, true));
dm.cancellaPersona(1);
assertEquals(2, dm.numeroInserimenti());
}
}
L'immagine seguente mostra che i test hanno entrambi successo:
Proviamo a modificare in maniera erronea la classe DataManager
if
void cancellaPersona(int pos)
{
// metodo sbagliato!
if (numeroInserimenti()<0)
elenco.remove(pos);
}
L'esecuzione del medesimo test rileverà quanto segue:
Come possiamo vedere, uno dei due test sarà errato in quanto il valore ottenuto dall'invocazione del metodo numeroInserimenti
È facile immaginare che sarà necessario pianificare una strategia di test molto più estesa di quelle viste negli esempi di questa lezione, come sarà discusso nelle prossime lezioni.