Je vous propose ici une introduction à l’API Espresso. Elle permet de réaliser des tests fonctionnels sur les applications Android de manière rapide et facile.
Espresso, c’est quoi ?
L’API Espresso (appartenant à Android Testing Support Library) permet de mettre en place des tests fonctionnels (Tests de Non Régression) en simulant les interactions possibles des utilisateurs avec l’application. Elle est légère et facile à prendre en main.
Lors de la création des tests, le développeur va pouvoir réaliser un certain nombre d’actions comme la récupération d’un composant, faire défiler une liste, cliquer sur un composant ou vérifier le texte affiché.
Les tests Espresso sur Android doivent être exécutés sur un terminal physique en USB ou via un émulateur car ils nécessitent une instance du système Android. Il est également possible d’utiliser Firebase Test Lab qui permet d’exécuter les tests sur une grande variété de périphériques physiques et virtuels simultanément.
Les pré-requis
Afin de pouvoir utiliser Espresso ainsi que ses outils, il vous faudra Android Studio 2.2 ou supérieur.
De plus, vous devrez avoir un terminal ou émulateur ayant une version Android 4.4 Kit Kat (API Level 19) ou supérieur.
Configuration
Pour importer Espresso, vous aurez besoin de la configuration suivante.
app/build.gradle
android {
...
defaultConfig {
...
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
lintOptions {
abortOnError false
}
packagingOptions {
exclude 'LICENSE.txt'
}
}
dependencies {
...
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support:support-annotations:25.3.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'
}
Les composants d’Espresso
Les tests Espresso peuvent être mis en place sur des applications à partir d’Android 2.2 Froyo, ils sont principalement construits à partir des composants suivants :
- Espresso : C’est le point d’entrée pour les interactions avec vos différentes vues. Elle propose les méthodes
onView()
etonData()
qui vous permettront de récupérer vos composants UI et vos données dans les AdapterView. - ViewMatchers : C’est une collection d’objets Matcher<? super View>. Elle permet de récupérer une vue à l’aide d’une ou plusieurs méthodes que l’on peut passer dans
onView()
. - ViewActions : C’est une collection d’objets ViewAction pouvant être passés dans la méthode
ViewInteraction.perform()
afin de pouvoir effectuer des actions sur une vue (Exemple : le clic, le scroll …). - ViewAssertions : C’est une collection d’objets ViewAssertion pouvant être passés dans la méthode
ViewInteraction.check()
afin de pouvoir comparer 2 objets. C’est ici que le développeur va comparer des états, des chaînes de caractères … Avant et/ou après des actions qu’il aura pu effectuer.
Exemple
onView(withId(R.id.myview)) // withId(R.id.my_view) est un ViewMatcher
.perform(click()) // click() est un ViewAction
.check(matches(isDisplayed())); // matches(isDisplayed()) est un ViewAssertion
Les ViewAssertions personnalisées
En plus des ViewAssertions proposées par Espresso, il est également possible d’en créer. Prenons comme exemple la couleur d’un texte.
onView(withId(R.id.myedittext)).check(matches(withTextColor(Color.BLACK)));
public static Matcher<View> withTextColor(final int color) {
Checks.checkNotNull(color);
return new BoundedMatcher<View, TextView>(TextView.class) {
@Override
public void describeTo(Description description) {
description.appendText("with text color: ");
}
@Override
protected boolean matchesSafely(TextView warning) {
return color == warning.getCurrentTextColor();
}
};
}
Les Extras data
Vous souhaitez tester une activité en particulier mais elle nécessite des Extras data (informations que l’on souhaite faire passer d’une Activity à l’autre en utilisant l’Intent). N’ayez pas peur, on va les créer.
Exemple
@Rule
public ActivityTestRule<LoginActivity_> rule = new ActivityTestRule<>(LoginActivity_.class, true, false);
@Before
public void initIntent() {
// Complete intent paramaters
Intent intent = new Intent();
intent.putExtra("myExtra", “Hello World”);
rule.launchActivity(intent);
}
Vérifier le passage à une nouvelle Activity
Il est déconseillé de réaliser les tests sur 2 Activity différentes dans une même classe, néanmoins il est possible de vérifier si, lors d’un clic sur un bouton, on est bien passé à l’Activity suivante.
Cette vérification peut être effectuée de la façon suivante :
- Activity 1 : cliquez sur un élément.
- Activity 2 : vérifiez que l’un des éléments de cette nouvelle vue existe bien.
- Activity 2 : revenez sur la première Activity avec pressBack().
- Activity 1 : vérifiez que l’un des éléments de l’Activity 1 existe bien.
Exemple
ViewInteraction profileId = onView(withId(R.id.profil_id));
profileId.check(matches(withText("ID client : 123456")));
ViewInteraction modifyPwd = onView(withId(R.id.modify_password));
modifyPwd.check(matches(isClickable()));
modifyPwd.perform(click());
// New Activity : ChangePasswordActivity
ViewInteraction textConfirmPwd = onView(withId(R.id.forget_pwd_confirm));
textConfirmPwd.check(matches(withText(R.string.confirm_pwd)));
pressBack();
// Go back to ProfilActivity
profileId.check(matches(withText("ID client : 123456")));
Plus besoin d’écrire
Maintenant que vous avez les bases pour créer vos tests vous-même, je vais vous parler de Espresso Test Recorder (à partir d’Android Studio 2.2 et Android 4.4 Kit Kat). C’est un outil qui vous permet de générer des tests sans avoir à les écrire (il est caché dans Run > Record Espresso Test).
Tout comme l’exécution des tests, il est nécessaire d’avoir un terminal physique en USB ou un émulateur.
Avant de commencer l’enregistrement, l’application va être buildée sur le terminal sélectionné. Puis la fenêtre “Record your test” apparaît, c’est à ce moment que vous allez pouvoir commencer à interagir avec l’application et voir apparaître vos actions dans la fenêtre prévue à cet effet.
Pendant l’enregistrement, il est possible de sélectionner un composant et de lui ajouter l’une des 3 types d’assertion :
- text is : Vérifier le contenu du composant
- exists : Vérifier que le composant existe dans la vue sélectionnée
- does not exist : Vérifier que le composant n’existe pas dans la vue sélectionnée
Tout ce qui était listé dans la fenêtre “Record your test” sera généré automatiquement dans un fichier identique à ceux que vous créez lorsque que vous réalisez vos tests manuellement. Il ne restera plus qu’à l’exécuter (attention, la transition entre les Activity n’est pas prise en compte dans les tests).
Une vidéo de démonstration est disponible ici.
Exemple de script généré par le recorder
@LargeTest
@RunWith(AndroidJUnit4.class)
public class RecordEspressoTest {
@Rule
public ActivityTestRule<LoginActivity_> mActivityTestRule = new ActivityTestRule<>(LoginActivity_.class);
@Test
public void recordEspressoTest() {
// 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
ViewInteraction editText = onView(
allOf(withId(R.id.idField),
withParent(withId(R.id.layout_input))));
editText.perform(scrollTo(), replaceText("myLogin"), closeSoftKeyboard());
ViewInteraction editText2 = onView(
allOf(withId(R.id.passField),
withParent(withId(R.id.layout_input))));
editText2.perform(scrollTo(), replaceText("myPassword"), closeSoftKeyboard());
ViewInteraction switch = onView(
allOf(withId(R.id.switch_connected), withText("Se souvenir de mon identifiant"),
withParent(withId(R.id.layout_input))));
switch.perform(scrollTo(), click());
ViewInteraction button = onView(
allOf(withId(R.id.buttonConnexion), withText("Se connecter"),
withParent(withId(R.id.layout_buttons))));
button.perform(scrollTo(), click());
}
}
Conclusion
Il n’y a plus besoin d’avoir de connaissances poussées pour intégrer des tests Espresso. Il suffit d’un peu de documentation, d’étudier le fichier généré grâce à Espresso Test Recorder et vous allez pouvoir vous perfectionner au fur et à mesure du temps.
Que ce soit pour les débutants ou confirmés, le gain de temps n’est pas négligeable notamment grâce à Espresso Test Recorder. Il va permettre de créer une structure de tests qui ne demandera que des modifications principalement pour les assertions qui n’ont pas pu être réalisées avec l’outil.
Le document ci-dessous référence les principales méthodes utilisées. Pour la liste complète, il faut vous rendre sur les documentations respectives (ViewMatchers, ViewActions, ViewAssertions …) disponibles ici.
Le format pdf est disponible ici