Comment produire et automatiser des tests fonctionnels

Comment produire et automatiser des tests fonctionnels
Les mathématiques sont formelles : tester exhaustivement toutes les fonctionnalités de votre application web vous prendra quelques milliards d’années. La force brute est vouée à l’échec en matière de tests fonctionnels. Certes ils doivent être automatisés par l’utilisation de robots, mais pour ce faire il faudra traduire du langage humain en langage machine, c’est à dire produire du code. Et c’est là que tout se joue.

Les deux principes fondamentaux des tests fonctionnels

Imaginons que votre application n’ait besoin que de 20 variables indépendantes pour fonctionner (nom d’utilisateur, rôle, nationalité, contenu du shopping cart, type d’abonnement, date de dernière visite, historique des actions, choix1, choix2, …). La théorie dit que pour la tester exhaustivement, il vous faudra mener 20! = 2,43.1018 tests. Ainsi, en estimant qu’un test passe en 1/1000ème de seconde sur votre banc de test, il vous faudra 2,43.1015 secondes, soit approximativement 77 millions d’années pour jouer la totalité de votre campagne de tests.

Les mathématiques sont donc têtues : la stratégie de testing fonctionnel par la force brute, qui consiste à demander aux informaticiens de « tout tester automatiquement », est trop coûteuse et trop lente, elle est illusoire. En outre elle viole un principe important : la neutralité du testeur. En effet si vous demandez à un informaticien de tester sa propre production, il sera juge et partie, et par conséquent les tests seront biaisés. Il choisira inconsciemment les chemins qui fonctionnent, mais pas forcément les chemins qu’emprunteront les utilisateurs.

De ce qui vient d’être écrit, il découle les deux principes fondamentaux des tests fonctionnels : d’une part tout tester n’est pas possible, et d’autre part les informaticiens ne doivent pas intervenir dans la phase de spécification des tests.

Est-ce alors à dire que l’automatisation des tests fonctionnels est impossible ? Certes non, mais il faut utiliser la bonne stratégie, et la bonne architecture.

La parabole de la maison en construction

Pour bien comprendre ce que sont les tests fonctionnel, utilisons la parabole de la maison en construction. Le fabricant d’interrupteur électrique fait des tests pour savoir si son produit fonctionne, c’est ce qu’on appelle le « test unitaire ». Ensuite l’électricien branche l’interrupteur sur le circuit électrique de la maison en construction, et il vérifie qu’une fois posé il allume correctement la lumière, c’est le « test d’intégration ». Enfin, le locataire de la maison emménage, et teste qu’il peut effectivement allumer la lumière, c’est le « test fonctionnel ». Et là, catastrophe, il ne parvient pas à trouver l’interrupteur. Ainsi les tests unitaire et d’intégration sont bien passés, mais le test fonctionnel a échoué, car l’interrupteur n’était pas à la bonne place. L’électricien pourra arguer en réponse que l’interrupteur est à la cave, car il n’avait plus assez de fil pour le ramener au salon, et qu’il suffit de descendre à la cave lorsqu’on veut de la lumière, mais à part ça tout fonctionne parfaitement. Ce choix est certes confortable pour l’électricien, mais beaucoup moins pour l’utilisateur à qui la maison est destinée.

Dans cet exemple la maison est votre applicatif, les fabricants et électriciens sont les informaticiens, et le locataire est l’utilisateur. On comprend avec cette image que si les tests unitaires et d’intégration sont bien effectivement de la responsabilité des informaticiens, les tests fonctionnels ne peuvent être conçus et réalisés que par les utilisateurs métier. C’est d’ailleurs pourquoi nombre d’entreprises effectuent leurs tests fonctionnels en mettant un humain devant la machine, ce dernier devant jouer une série de tests spécifiés au préalable (aller sur le site, entrer « toto » dans le champ de login, entrer « xxx » dans le champ mot de passe, cliquer sur « valider », …)

Le métier responsable des tests fonctionnels

Seul un humain saura choisir les tests pertinents parmi les 2,43.1018 tests possibles (au moins). Mais bien sûr cet humain doit connaître le contexte métier dont traite l’application. Si nos informaticiens sont de brillant personnages, leur métier est l’informatique, pas la banque, ni la distribution, ni l’aéronautique, ni la vente en ligne, … Dès lors, leur demander d’apprendre un autre métier en plus du leur, afin de comprendre pourquoi tel test fonctionnel est plus pertinent qu’un autre, reviendrait à  demander au métier d’apprendre l’informatique. Il faut une vie pour devenir un expert dans un domaine. Si on sait tout faire, on fait tout médiocrement, mais si on ne sait faire qu’une chose, on peut la faire excellemment. Donc chacun son rôle : l’informaticien informatise, le métier spécifie le fonctionnel, tests y compris.

C’est d’ailleurs bien le besoin métier qui déclenche un projet applicatif. Le métier émet un cahier des charges en langage humain, qui est ensuite transmis aux informaticiens pour sa mise en œuvre. L’informaticien ne sait pas a priori que tel utilisateur de tel métier a besoin d’une application, avec telle et telle fonctionnalités. C’est le métier qui spécifie les fonctionnalités de l’application. Et bien il en va de même pour les tests fonctionnels. C’est aussi lui qui spécifie les tests à effectuer pour valider le fonctionnement de l’application.

Certains projets sont même « test driven ». Cela consiste à émettre le cahier des charges sous forme de spécification de tests. Le métier spécifie ce qu’il veut voir sur l’écran, et le comportement des différents éléments de la page affichée, tandis que les informaticiens transforme ces spécifications humaines, en un code jouable par la machine.

Les stratégies des tests fonctionnels

Les tests fonctionnels sont long, coûteux et fastidieux à mener manuellement, d’autant qu’ils doivent être joués souvent, c’est à dire à chaque modification du code, ne serait-ce que pour vérifier que la dernière mise à jour n’a pas impacté les fonctionnalité. On parle alors de tests de non régression. L’idéal est bien sûr que des robots fassent les tests automatiquement, sans besoin d’intervention humaine. Or il faut expliquer aux robots la tâche qu’ils doivent effectuer, en langage robot, c’est à dire en code informatique, et ça seulement les informaticiens savent faire.

Nous sommes donc dans la situation inconfortable de posséder des spécifications de tests en langage humain, qu’on doit traduire en langage machine, le code. C’est ici que la stratégie à appliquer devient cruciale. Comment passe-t-on du langage humain en langage machine ? Il existe pour cela 3 stratégies :

  • le recording,
  • la programmation manuelle,
  • la programmation automatique.

Le recording : il s’agit de placer un humain qui lit les spécifications et les joue sur son écran. Toutes ses actions sont enregistrées et produisent un code, qu’une machine de test pourra automatiser. En théorie c’est parfait, mais en pratique c’est la pire des solutions. En effet les codes obtenus sont non structurés, ce qui fait qu’ils doivent être réenregistré à chaque modification de l’applicatif. 2 joueurs jouant les mêmes spécifications produiront deux codes différents. En outre le recording ne peut pas vérifier la présence, ni le contenu, ni la couleur, ni rien de passif.

La programmation manuelle : il s’agit de demander aux informaticiens de programmer les tests spécifiés en langage humain. C’est une bonne solution car on obtient alors des codes structurés qui n’auront pas besoin d’être réécrits à la moindre modification de l’application. En revanche l’informaticien va s’ennuyer ferme car la programmation des tests est élémentaire au regard de ce qu’est le codage au sens propre du terme. C’est très luxueux d’utiliser les compétences d’un informaticien pour accomplir des tâches de si bas niveau. C’est le défaut de cette solution : elle est coûteuse.

La programmation automatique : il s’agit de produire des codes de test structurés sans intervention d’un informaticien. C’est la solution funKTest. On propose au métier une interface où il pourra spécifier ses tests fonctionnels en langage humain, puis on demande à un technicien de spécifier les éléments html concernés, grâce à une interface intuitive, sur de simples clics de souris. FunKTest produit alors un code Protractor qui est automatisable sur un banc de test. En supplément, si votre applicatif est joignable sur internet, vous pouvez exécuter ces tests sans avoir aucun banc de test.

La programmation automatique est donc certainement la solution structurée la moins chère, la plus rapide et la plus simple à mettre en œuvre.

Que faire quand on a le code de test

Lorsque votre code de test a été produit, c’est à dire après avoir appliqué une des trois stratégies décrites plus haut, il vous faut le fournir à un robot pour qu’il le joue. Ce robot ne sera rien d’autre qu’un banc de test doté de machines dédiées aux tests. Un logiciel d’intégration continue tel que Jenkins par exemple, se chargera de lancer automatiquement les tests sur ces machines, aux heures et dates voulues.

Mais si vous n’avez rien de tout ça, vous pouvez rendre votre site visible sur internet, puis utiliser funKTest pour jouer les tests. C’est simple et immédiat.

About the author: Enora Le Cornec