À la une

Les tests End to End Flutter avec RobotFramework

Chez XPEHO on aime la mobilité et on aime aussi les applications de qualité.

Beaucoup de développeurs vous le diront. : Tester c’est douter. Oui, mais dans le doute, il vaut mieux tester !

 

 

 

Les tests automatisés, qu’est-ce que c’est ?

Les tests automatisés font partie intégrante d’un développement. Il est très confortable de pouvoir exécuter une suite de tests pour s’assurer de la non-régression après avoir effectué une modification dans le code. C’est une bonne pratique qui permet de créer et de maintenir des applications de meilleure qualité. Même si les tests automatisés ne remplaceront jamais les tests effectués par un être humain, ils permettent de vérifier très rapidement l’indice de confiance et de qualité de ce qu’on s’apprête à livrer.

Les différents tests avec Flutter

Les tests unitaires

C’est le plus bas niveau de granularité. Ce sont des tests très petits qui permettent de tester une seule méthode. Par convention, il est préférable d’utiliser des mocks pour tout appel vers l’extérieur de la méthode testée. Par exemple : si la méthode testée fait appel à une API, on remplacera l’appel API par un Mock.

Les tests widget

On teste ici chaque widget de manière indépendant. Ces tests permettent de valider le comportement d’un widget personnalisé en fonction du cycle de vie et des actions effectuées.

On peut ainsi tester le comportement et les changements graphiques de notre widget en fonction des actions effectuées dessus.

Les tests Golden

C’est une variante des tests widget. On teste ici le rendu graphique d’une vue.  Ces tests permettent de générer une image de ce à quoi est censé ressembler le widget en fonction de différentes conditions (résolution, écran téléphone ou tablette, etc…). Lors que ces tests s’exécutent, ils vont comparer une image de référence au rendu du widget testé. On peut ainsi trouver facilement les impacts potentiels sur toutes les vues de notre application suite à un changement de thème ou de police.

Je vous conseille cet article qui parle des tests widget de façon plus détaillée.

Les tests d’intégration

Les Integration Tests de Flutter sont ce qui se rapprochent le plus des tests utilisateurs. Ils permettent de tester les différents parcours de l’application, la navigation et les gestes métier. Tous comme les autres tests, ils permettent de bouchonner les appels API en les remplaçant par des Mocks. De cette manière, vous serrez capable de valider la totalité des parcours graphique de votre application et en même temps de maîtriser vos données.

Vous pouvez bien entendu laisser vos API telles qu’elles sont, mais vous serez alors dépendant de données sur lesquelles vous n’avez aucun contrôle et votre test risquera d’échouer en fonction du contenu de ces données.

Mocks, qu’est-ce que c’est ?

En anglais, to mock peut se traduire par « singer » ou « imiter ». C’est une pratique qui consiste à remplacer le comportement d’un morceau de code par un faux comportement dans le but de contrôler le bon déroulement de nos tests.

Par exemple, si vous cherchez à tester le bout de code qui interprète la réponse d’un appel API, vous allez remplacer le bout de code qui appel l’API par un mock.

Dans votre premier test, vous allez vérifier le comportement quand tout se passe bien et dire à votre mock de renvoyer une réponse success. Enfin, dans votre second test, vous allez vérifier le comportement lorsque l’API vous renvoie une erreur et dire à votre mock de renvoyer une réponse error.

La plus répandue des librairies de mocks Java est Mockito pour Mock It To. Flutter propose sa version de Mockito pour Dart. Et si vous faites du Kotlin, je vous recommande Mockk pour faire vos mocks.

 

 

Les tests end to end

C’est quoi ?

Traduisez tests de bout en bout. Ces tests vont permettre de tester l’intégralité des briques qui permettent le bon fonctionnement d’une application. Une application mobile n’est pas toujours autonome, elle utilise parfois (voire souvent) des API HTTP, des bases de données, d’autres applications, les capteurs du téléphone etc…

A quoi ça sert ?

Les tests end to end permettent de tester automatiquement les scénarii fonctionnels d’une application. On y déroule une série de gestes ou d’actions que l’utilisateur est censé effectuer dans le but de vérifier le bon fonctionnement de l’application.

Cette catégorie de test nécessite plus d’efforts pour les mettre en place. Il est donc important de se limiter aux 20/80 (20% des cas qui représentent 80% de la valeur de l’application). Entendez par là qu’il faut se limiter aux cas nominaux et éviter de tester l’intégralité des cas possibles ou des erreurs potentielles.

Pourquoi en faire ?

Cette catégorie de tests est très adaptée pour vérifier rapidement si la dernière version de l’application contient ou non des régressions. Elle permet d’obtenir un indice de confiance sur la qualité de la version actuelle de l’application.

Difficultés rencontrées

L’une des particularités de Flutter est le moteur de rendu Skia https://skia.org/.  Ce moteur permet d’afficher le contenu de l’interface utilisateur d’une application Flutter. En gros, Flutter affiche une vue native dans laquelle il dessine ses propres pixels.

Les outils existants qui permettent de faire des tests end to end fonctionnent tous de la même manière :

  1. Localiser une vue ou un élément sur l’écran d’une application
  2. effectuer une action sur cet élément (clic, assertion…)

Comme Flutter ne dispose que d’une seule vue, il est donc impossible de procéder de la même manière puisque les différents éléments de l’interface ne sont pas accessibles depuis l’extérieur de l’application.

De ce fait, les outils traditionnels de tests end to end ne peuvent pas tester une application Flutter.

Comment en faire alors ?

Il suffit de trouver un moyen de mettre en place un robot de test qui procède de la même manière qu’un être humain. Lorsque nous utilisons une application, nous utilisons 3 outils :

  • Nos yeux
  • Notre cerveau
  • Nos mains

Un robot qui devrait faire de même doit donc les inclure :

  • La reconnaissance d’images ou de texte ferait office d’œil
  • Le scénario de test remplacerait le cerveau
  • Un robot de test comme Appium remplacerait les mains

RobotFramework

RobotFramework c’est quoi ?

C’est un outil d’automatisation de tests qui sait à peu près tout faire. IHM, API, serveurs, BDD, desktop, web, mobile ou un peu de tout ça en même temps, il sait le faire sans souci.

Plus d’infos sur https://robotframework.org/

Comment ça fonctionne ?

C’est basé sur Python. Le principe de fonctionnement est assez simple.

On crée des fichiers *.robot dans lesquels on écrit des tests dans la langue souhaitée. Anglais, français, espéranto, c’est vous qui choisissez.

 

 

 

Par exemple

*** Settings ***
Resource        welovedevs_keywords.resource
*** Test Cases ***
Read previous post
 Open Google Chrome
 Read post        https://welovedevs.com/fr/articles/cicd-flutter-avec-github-actions-par-xpeho/

Ensuite, vous devez définir ce que « Open Google Chrome » et « Read post » vont faire dans le fichier « welovedevs_keywords.resource »

 

*** Settings ***
Library         Browser

*** Keywords ***

Open Google Chrome
 New Browser     chromium    headless=false  slowMo=0:00:00.050
 New Context     viewport={'width': 1920, 'height': 1080}
 

Read article
 [Arguments]     ${url}
 New Page        ${url}
 Get Title       ==      Google

On utilise ici une librairie « browser » qui permet de manipuler le navigateur web de votre ordinateur.

Plus d’infos sur les librairies de RobotFramework sur https://robotframework.org/#resources

Comment l’utiliser pour Flutter ?

Sur nos trois outils, les yeux, le cerveau, les mains, il ne nous manque plus que les yeux.  Si vous avez bien suivi, Appium fera les clics sur le téléphone et RobotFramework contiendra la partie intelligente, à savoir les scénarii de tests.  Et bien bonne nouvelle, RobotFramework a des librairies capables de donner la vue à nos tests !

On a besoin de savoir reconnaître 2 choses :

  • du texte
  • des images

Pour le texte, il nous faut une librairie d’OCR. Il s’agit de reconnaitre du texte à l’intérieur d’une image. Et on fera ça avec OCRLibrary https://pypi.org/project/robotframework-ocrlibrary/

Pour les images, il nous faut ce qui s’appelle de l’image template. C’est le fait de trouver une image à l’intérieur d’une image plus grande. Et tout ça grâce à OpenCV de Python https://pyimagesearch.com/2021/03/22/opencv-template-matching-cv2-matchtemplate/

Un exemple

On a créé une petite application en Flutter avec des scénarii de tests RobotFramework

L’application de base générée par Flutter est plutôt simple. Nous avons donc ajouté quelques éléments pour avoir de quoi tester.

Avant de pouvoir tester quoi que ce soit, il faut construire l’application et l’installer sur l’émulateur Android.

Dans un terminal à la racine du projet tapez

flutter build apk --debug

et

flutter install

Maintenant écrivons un premier test dans un fichier counter_app.robot pour vérifier qu’on arrive à incrémenter le compteur

*** Settings *** 
Documentation Counter app test suite 
Resource counter_app_keywords.resource 
Test Setup Open the counter app 
Test Teardown Close the counter app 

*** Test Cases *** 
Counter app increment counter 
 Given I have opened the counter app 
 When I click on the increment button 6 
 Then the counter should incremented by 6

Définissons les mots clés dans le fichier counter_app_keywords.resource

*** Settings ***
Documentation TODO
Library AppiumLibrary
Library OCRLibrary
Library Collections
Library custom_lib.py

*** Variables ***

${APP} com.example.flutter_tests
${IMAGE_DIR} ${CURDIR}/images
${ANDROID_AUTOMATION_NAME} UIAutomator2
${IOS_PLATFORM_NAME} iOS
${ANDROID_PLATFORM_NAME} Android
*** Keywords *** 

Open The counter app
 Open Application http://localhost:4723/wd/hub automationName=${ANDROID_AUTOMATION_NAME}
 ...platformName=${ANDROID_PLATFORM_NAME}
 ... app=${CURDIR}/../../build/app/outputs/flutter-apk/app-debug.apk

Close The counter app
 Close Application

Given I have opened the counter app
     Find Text You have pushed the button this many times:
     Find Text 0

When I click on the increment button
     [Arguments]${clickCount}
     Click Image plus_button.png ${clickCount}

Then the counter should incremented by
     [Arguments]${clickCount}
     Find Text ${clickCount}
Et enfin, le contenu de notre lib custom_lib.py en Python
import cv2
import numpy as np

def assert_text_was_found(coordinatesList, text):
    if coordinatesList is None:
        print('Text ' + text + ' was found')
        raise Exception("Text '{}' was not found".format(text))
    elif len(coordinatesList) == 0:
        print('Text ' + text + ' was not found')
        raise Exception("Text '{}' was not found".format(text))
    else:
        print('Text ' + text + ' was found')
        

def find_sub_image(im1, im2):
    needle = cv2.imread(im1)
    haystack = cv2.imread(im2)

    result = cv2.matchTemplate(needle, haystack, cv2.TM_CCOEFF_NORMED)
    y, x = np.unravel_index(result.argmax(), result.shape)
    x += (needle.shape[1]/2)
    y += (needle.shape[0]/2)
    return x, y
Il ne reste plus qu’a lancer la commande suivante dans un shell
robot counter_app.robot
Et voilà !

Des cas plus complexes ainsi que la totalité des sources sont disponibles sur notre repo Git.

Conclusion

Nous venons de créer un outil qui permet de faire des tests End To End facilement sur des applications Flutter mobiles. Cet outil est capable de chercher, trouver et interagir avec des éléments dans l’interface de notre application. Ces éléments peuvent être des images ou du texte.

Si un élément change de position dans l’écran, notre outil est capable de le retrouver sans faire de modification à nos tests. Il est possible de faire fonctionner ces tests sur Flutter Web ou même sur Flutter Desktop avec un jeu de librairie RobotFramework différente.

Le mot de la fin

Les tests sont une partie souvent trop négligée dans notre métier. Pourtant, ils permettent avec très peu d’investissement de s’assurer de la qualité de notre application.

Flutter est très bien outillé pour faire des tests et l’outil qu’on vient de créer permet de tester nos applications à un niveau supplémentaire alors pourquoi se priver ?

Piotr Fleury

Recent Posts

Communauté Tech et féminine : Interview avec Helvira de Motiv’her

Elles sont passées où les femmes dans la tech ? Entre le manque de représentation…

3 jours ago

Consommer des APIs HTTP en PHP comme un pro avec Nicolas Grekas.

Dans cette vidéo, on interview Nicolas Grekas, contributeur clé de Symfony, pour discuter de sa…

3 jours ago

Trouver son job grâce à WeLoveDevs.

 Comment trouver son job dans la tech ? Marie a la réponse ! Grâce à…

5 jours ago

Adobe, L’empire créatif.

Adobe, l'empire créatif, et pas des moindres ! Belle ascension de la part de ces…

1 semaine ago

La MAO musique ou musique assistée par ordinateur

Est-ce plus simple de créer des morceaux avec les outils de Musique Assistée par Ordinateur…

1 semaine ago