Tester la navigation

1. Avant de commencer

Dans les précédents ateliers de programmation, vous avez appris à naviguer entre les activités. Dans cet atelier, vous allez découvrir différentes approches pour tester la navigation à l'aide de tests d'instrumentation.

Conditions préalables

  • Vous avez créé des répertoires de test dans Android Studio.
  • Vous avez rédigé des tests unitaires et d'instrumentation dans Android Studio.

Points abordés

  • Comment utiliser les tests d'instrumentation pour tester la navigation physique entre des activités ou des fragments.

Ce dont vous avez besoin

  • Un ordinateur sur lequel est installé Android Studio
  • Le code de solution de l'application Words

Télécharger le code de démarrage pour cet atelier de programmation

Dans cet atelier de programmation, vous allez ajouter des tests d'instrumentation au code de solution de l'application Words.

Pour obtenir le code de cet atelier de programmation et l'ouvrir dans Android Studio, procédez comme suit :

Obtenir le code

  1. Cliquez sur l'URL indiquée. La page GitHub du projet s'ouvre dans un navigateur.
  2. Sur la page GitHub du projet, cliquez sur le bouton Code pour afficher une boîte de dialogue.

5b0a76c50478a73f.png

  1. Dans la boîte de dialogue, cliquez sur le bouton Download ZIP (Télécharger le fichier ZIP) pour enregistrer le projet sur votre ordinateur. Attendez la fin du téléchargement.
  2. Recherchez le fichier sur votre ordinateur (il se trouve probablement dans le dossier Téléchargements).
  3. Double-cliquez sur le fichier ZIP pour le décompresser. Un dossier contenant les fichiers du projet est alors créé.

Ouvrir le projet dans Android Studio

  1. Lancez Android Studio.
  2. Dans la fenêtre Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur Open an existing Android Studio project (Ouvrir un projet Android Studio existant).

36cc44fcf0f89a1d.png

Remarque : Si Android Studio est déjà ouvert, sélectionnez l'option de menu File > New > Import Project (Fichier > Nouveau > Importer un projet).

21f3eec988dcfbe9.png

  1. Dans la boîte de dialogue Import Project (Importer un projet), accédez à l'emplacement du dossier du projet décompressé. Il se trouve probablement dans le dossier Téléchargements.
  2. Double-cliquez sur le dossier de ce projet.
  3. Attendez qu'Android Studio ouvre le projet.
  4. Cliquez sur le bouton Run (Exécuter) 11c34fc5e516fb1c.png pour créer et exécuter l'application. Assurez-vous qu'elle fonctionne correctement.
  5. Parcourez les fichiers du projet dans la fenêtre d'outil Project (Projet) pour voir comment l'application est configurée.

2. Présentation de l'application de démarrage

L'application Words se compose d'un écran d'accueil qui affiche une liste dont chaque élément est une lettre de l'alphabet. Cliquez sur une lettre pour accéder à un écran contenant une liste de mots commençant par cette lettre.

3. Bonnes pratiques

En Kotlin, on utilise, par convention, le format "camel case" pour attribuer des noms de fonction. Concrètement, cela signifie que la première lettre du nom de fonction est une minuscule et la première lettre des mots suivants est une majuscule (par exemple, myCamelCaseFunction()). Les méthodes de test que nous avons écrites jusqu'à présent utilisaient des lettres minuscules et des traits de soulignement entre les mots (par exemple, my_test_function()). L'objectif est d'avoir des noms de fonction suffisamment détaillés pour indiquer explicitement ce qui est testé. Ainsi, en cas d'échec du test, le nom seul indique clairement ce qui a échoué. En Kotlin, il est même possible d'utiliser des espaces dans un nom de méthode s'il est encapsulé dans des accents graves, comme ceci : ``test function with spaces(). Notez qu'un accent grave est différent d'un guillemet simple. Sur les claviers anglais, ce signe se trouve sur la touche avec le tilde (~). Cela permet de créer des noms de fonction lisibles et faciles à identifier en cas d'échec.

Le problème de cette méthode, c'est que son implémentation nécessite une configuration. Gardez à l'esprit que cette section est facultative. Nous vous encourageons à la lire, mais aucune étape n'est obligatoire avant la section "Créer le répertoire des tests d'instrumentation".

  1. Notez que le nom de la fonction ne peut contenir des espaces que si vous ciblez l'API 30 sous Android. Sinon, un message d'erreur semblable à celui-ci peut s'afficher :

4333fe8605801dba.png

Pour modifier l'API, accédez à app/build.gradle, puis modifiez minSdkVersion et/ou targetSdkVersion :

a6207c31c66ca185.png

Dans ce cas, targetSdkVersion est défini sur 30, qui est la valeur requise. Toutefois, minSdkVersion est défini sur 19. Nous devons donc le remplacer par 30 pour autoriser les espaces dans les noms de fonction. Comme cela n'est pas toujours pratique, on considère que cette fonctionnalité est souhaitable, mais pas obligatoire.

  1. Même si vous ciblez l'API 30, vous constaterez que la méthode est soulignée en rouge avec le message Identifier not allowed in Android Projects (Identifiant non autorisé dans les projets Android).

d1330d69cc2472b1.png

Le test continue de s'exécuter jusqu'à la fin. Toutefois, pour supprimer le soulignement, accédez aux paramètres/préférences d'Android Studio et sélectionnez Éditeur -> Inspections -> Kotlin Android -> Identifiant Android illégal -> Tests.

acc4a31499bdb25.png

Décochez ensuite la case Tests, puis cliquez sur Appliquer ou sur OK.

aeb57d303996a3de.png

Vos méthodes ne sont plus soulignées en rouge, à condition que vous placiez leur nom entre des accents graves.

a54f3eff47697024.png

4. Créer le répertoire de tests

Créez un répertoire de tests d'instrumentation pour l'application Words.

5. Créer une classe de test d'instrumentation

Créez une classe appelée NavigationTests.kt.

9d9ee307b4773b7.png

6. Écrire le test de navigation

  1. Spécifiez un lanceur de test.
@RunWith(AndroidJUnit4::class)
  1. Lancez ensuite l'activité principale.
@get:Rule
val activity = ActivityScenarioRule(MainActivity::class.java)
  1. Créez à présent une méthode appelée navigate_to_word().
@Test
fun navigate_to_word() {
}
  1. Dans les méthodes navigate_to_word(), nous devons sélectionner un élément de liste. L'élément que nous choisissons est arbitraire et il existe plusieurs façons de faire. Nous pouvons choisir un élément en fonction de sa position dans l'adaptateur ou en fonction du texte (c'est-à-dire de la lettre) qu'il contient. N'oubliez pas que si vous choisissez d'interagir directement avec RecyclerView, vous avez besoin de la dépendance suivante :
dependencies {
    ...
    androidTestImplementation
‘com.android.support.test.espresso:espresso-contrib:3.0.2'
}

En revanche, si vous sélectionnez un élément en fonction du texte, vous pouvez employer la méthode withText() que vous avez utilisée dans les ateliers de programmation précédents. Notez que si vous utilisez cette approche et que le texte n'apparaît pas à l'écran, le test échouera. Nous y reviendrons plus tard.

  1. Essayez les deux méthodes. N'oubliez pas que l'objectif est de cliquer sur le composant de l'interface utilisateur une fois qu'il a été trouvé.

Les deux approches sont présentées ici, le but étant de cliquer sur l'élément correspondant à la lettre "C", par exemple.

onView(withText("C")).perform(click())
onView(withId(R.id.recycler_view))
   .perform(RecyclerViewActions
       .actionOnItemAtPosition<RecyclerView.ViewHolder>(2, click()))

Prenez le temps d'examiner en détail ces deux approches. Si vous exécutez l'une ou l'autre et que vous observez votre émulateur ou votre appareil, vous constaterez que les deux fonctionnent. RecyclerViewActions nécessite davantage de code, mais permet de cliquer sur n'importe quel élément sans que cela n'exige de travail supplémentaire. Effectuez la première méthode, mais remplacez la lettre "C" par "Z" et exécutez à nouveau le test. Vous constaterez que le test échoue avec l'erreur suivante : androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "Z".

3c518d4b00624af3.png

En effet, la lettre "Z" figure à la fin de la liste et se trouve hors de l'écran au lancement de l'application, et l'utilisateur doit faire défiler la liste pour y accéder. La méthode RecyclerViewAction gère naturellement ce comportement. Essayez de transmettre 25 comme valeur de position et observez votre émulateur ou votre appareil.

  1. Si vous avez exécuté les exemples ci-dessus, vous avez vu que le lancement de l'activité suivante avait réussi. Toutefois, nous voulons vérifier cela à l'aide d'une assertion. Si vous exécutez l'application proprement dite et que vous cliquez sur un élément de liste donné, vous constatez que le titre de la barre d'application indique "Words That Start With __" (Mots qui commencent par __), où l'espace correspond à la lettre sur laquelle vous avez cliqué. Nous pouvons utiliser cela pour vérifier que la navigation fonctionne correctement. Il suffit d'affirmer que la chaîne correcte, suivie de la lettre sur laquelle nous avons cliqué, est affichée. Comme vous avez déjà effectué des assertions semblables dans des ateliers précédents, essayez de le faire par vous-même.
onView(withText("Words That Start With C")).check(matches(isDisplayed()))

7. Leçon théorique et bonnes pratiques

Deux termes très importants sont utilisés dans le domaine des tests : "faux positif" et "faux négatif".

On parle de "faux positif" lorsqu'un test génère un résultat positif, bien qu'il y ait un problème et que le test devrait échouer. On parle de "faux négatif" lorsqu'un test génère un résultat d'échec alors que tout est correct et que le test devrait réussir.

Dans le test que nous avons rédigé ci-dessus, nous avons codé en dur la chaîne recherchée. Au niveau du code, il serait préférable de créer la chaîne à partir des ressources de chaîne, comme dans l'application. Le fonctionnement est légèrement différent par rapport au code standard, mais cela reste possible. Cependant, créer la chaîne de cette manière pourrait échouer car, d'un point de vue technique, cette opération est une logique métier. Si la création de la chaîne dans le test échoue de la même manière que dans le code de l'application, cela risque de générer un faux positif. Cela est dû au fait que les deux extraits de code ont créé la même chaîne de manière incorrecte. Par conséquent, le texte incorrect du test correspond au texte incorrect affiché dans l'application. Il est donc préférable de coder en dur la chaîne sur la valeur attendue.

8. Code de solution

9. Félicitations

Voici les connaissances que vous avez acquises au cours de cet atelier de programmation :

  • Comment créer des noms de fonction détaillés pour les tests
  • Comment tester la navigation physique avec des activités ou des fragments
  • Ce que sont les "faux positifs" et les "faux négatifs"