• 20 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 12/12/2019

Tips et Tricks pour améliorer votre code

Pfiouuuu ! Vous avez appris à réaliser tellement de choses dans ce cours que vous devez avoir la tête aussi grosse qu'une patate... :lol:

                                                                         

Vous savez maintenant créer des requêtes réseaux performantes en arrière-plan et les afficher dans une belle RecyclerView, tout en laissant la possibilité à vos utilisateurs d'interagir avec. Encore bravo !

Dans ce chapitre, j'aimerais maintenant vous montrer comment tester votre code, et notamment vos requêtes réseau. Pour cela, nous allons créer des tests fonctionnels !

Hein ? Quelle est la différence avec les tests unitaires ? :o

Eh bien les tests unitaires valident et confirment qu'un morceau de code renvoie bien un résultat attendu, en fonction de paramètres d'entrée donnés. Généralement, ces derniers valident le bon fonctionnement de méthodes ou de fonctions uniques.

Les tests fonctionnels quant à eux, valident une suite logique et ordonnée d'opérations amenant à un résultat attendu.

Créer des tests fonctionnels sur nos requêtes réseau

Comme nous avons pu le voir dans les précédents chapitres, nos requêtes réseau sont encapsulées dans des streams RxJava. Nous avons placé tous ces flux dans une classe Java appelée GithubStreams.java.

Il serait maintenant intéressant de tester l'ensemble de ces streams de manière automatisée sur Android Studio non ? :)

Et bien c'est ce que nous allons faire immédiatement. Reprenons notre application NetApp, disponible également à ce commit. Nous allons créer une classe appelée MainFragmentTest.java dans le répertoire src/androidTest/java/com.openclassrooms.netapp :

Répertoire de nos tests unitaires
Répertoire de nos tests fonctionnels

Puis, nous allons tester ici les deux principales streams utilisées au sein de notre application, afin d'être sûr que ces dernières renvoient toujours les bonnes informations à savoir :

  • streamFetchUserFollowing(String username): La liste des utilisateurs Github que suit un utilisateur spécifié par la variable username.

  • streamFetchUserInfos(String username)  : Les informations personnelles d'un utilisateur spécifié par la variable username.

Reprenons notre classe de test MainFragmentTest.java. Elle devrait ressembler actuellement à cela :

Classe MainFragmentTest.java :

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {
    
}

Explications : Cette classe lancera des tests instrumentalisés en utilisant le système Android afin de fonctionner correctement. Cela nous permettra d'être au plus proche de la réalité.

Créons maintenant un test fonctionnel nous permettant de tester si la stream  streamFetchUserFollowing()  retourne les bonnes informations pour l'utilisateur Jake Wharton, à savoir la liste des utilisateurs qu'il suit.

Classe MainFragmentTest.java :

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {

    @Test
    public void fetchUserFollowingTest() throws Exception {
        //1 - Get the stream
        Observable<List<GithubUser>> observableUsers = GithubStreams.streamFetchUserFollowing("JakeWharton");
        //2 - Create a new TestObserver
        TestObserver<List<GithubUser>> testObserver = new TestObserver<>();
        //3 - Launch observable
        observableUsers.subscribeWith(testObserver)
                .assertNoErrors() // 3.1 - Check if no errors
                .assertNoTimeout() // 3.2 - Check if no Timeout
                .awaitTerminalEvent(); // 3.3 - Await the stream terminated before continue

        // 4 - Get list of user fetched
        List<GithubUser> usersFetched = testObserver.values().get(0);

        // 5 - Verify if Jake Wharton follows only 12 users...
        assertThat("Jake Wharton follows only 12 users.",usersFetched.size() == 12);
    }
}

Explications : Nous avons créé ici un test fonctionnel exécutant notre stream  streamFetchUserFollowing()  et vérifiant que celle-ci renvoie correctement les valeurs attendues. Comme vous le voyez, notre test est court, concis et lisible.

  • Ligne 1 : Nous récupérons notre Observable (donc notre stream) depuis la classe GithubStreams. Nous indiquons un nom d'utilisateur sur lequel porter les tests (ici Jake Wharton). En pratique, évitez de réaliser des tests sur des ressources réseau susceptibles d'évoluer (Peut-être qu'un jour, Jake Wharton supprimera son compte Github ? :'( )

  • Ligne 2 : Nous créons un Subscriber de test, grâce à la classe TestObserver que RxJava met à notre disposition afin de faciliter nos tests.

  • Ligne 3 : Nous lançons ici notre stream. Puis, nous lui chainons plusieurs méthodes :

    • Ligne 3.1 : Nous vérifions qu'aucune erreur n'est levée lors de l'exécution de la stream.

    • Ligne 3.2 : Nous vérifions que notre API répond bien et que notre stream ne dépasse pas sa limite de Timeout définie (10 secondes).

    • Ligne 3.3 : On attends que notre stream ait terminé avant de continuer l'exécution de notre test.

  • Ligne 4 : Notre stream réseau étant normalement à ce point terminée, nous pouvons récupérer les valeurs qu'elle a émises (et donc la liste des utilisateurs suivis par Jake Wharton).

  • Ligne 5 : Grâce à la méthode  assertThat()  , nous allons pouvoir tester que les valeurs renvoyées sont bien correctes. Dans notre cas, on vérifie que Jake Wharton suit bien 12 personnes seulement (12 personnes à l'heure où j'écris ce cours, mais cela peut évoluer !).

Réalisons également un second test sur cette fois-ci, la stream  streamFetchUserInfos()  .

Extrait de MainFragmentTest.java :

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {

    ...

    @Test
    public void fetchUserInfosTest() throws Exception {
        Observable<GithubUserInfo> observableUser = GithubStreams.streamFetchUserInfos("JakeWharton");
        TestObserver<GithubUserInfo> testObserver = new TestObserver<>();

        observableUser.subscribeWith(testObserver)
                .assertNoErrors()
                .assertNoTimeout()
                .awaitTerminalEvent();

        GithubUserInfo userInfo = testObserver.values().get(0);

        assertThat("Jake Wharton Github's ID is 66577.",userInfo.getId() == 66577);
    }
}

Explications : Le procédé est ici le même que pour le premier test. Cependant, nous testons maintenant la stream  streamFetchUserInfos()  qui est censée retourner les informations personnelles d'un utilisateur Github (ici Jake Wharton). La condition pour que le test s'achève avec succès est que l'identifiant soit égal à 66577 (l'identifiant Github unique de Jake Wharton).

Exécutons maintenant l'ensemble de ces tests. Pour cela, cliquez sur les flèches vertes imbriquées pour lancer ces deux tests l'un à la suite de l'autre.

Exécuter l'ensemble des tâches
Exécution de l'ensemble des tâches

Et voilà ! Android Studio va maintenant lancer l'exécution de ces tests. Vous n'avez plus qu'à attendre et prier pour que tout se passe bien... :lol:

                                    

Vous devriez pouvoir suivre la progression des tests ainsi que leur fin directement depuis la console d'exécution d'Android Studio.

Exécution des tests réussie
Exécution des tests réussie

Félicitations ! Vous venez de créer des tests fonctionnels qui vous permettront de valider la bonne exécution des deux streams précédemment créées dans votre application NetApp.

Conclusion

Et voilà, ce cours s'achève enfin ! Les appels réseau, l'exécution de tâches en arrière-plan ou encore la RecyclerView n'ont désormais plus aucun secret pour vous... :) Vous êtes maintenant capables de réaliser des applications Android performantes et surtout connectées !

Ne vous reposez cependant pas sur vos lauriers, et pensez à pratiquer, pratiquer et encore pratiquer afin que développer sous Android devienne aussi naturel que respirer... ;)

A très bientôt dans un prochain cours !

Exemple de certificat de réussite
Exemple de certificat de réussite