Bonjour à tous ! Alors bien évidemment, il serait absurde de vouloir lister toute les erreurs possibles, et totalement illusoire de croire que j'en n'en fait plus ; mais je crois pouvoir donner quelques exemples de ce qu'il faut éviter à tout prix lorsque l'on fait du développement piloté par le comportement avec Behat.
Petit rappel : Behat, c'est quoi ? En un mot, c'est un outil qui va vous permettre de pratiquer du BDD (Behavior Driven Development) en PHP. En d'autres mots, il va vous permettre de tester automatiquement si le développement d'un produit correspond aux spécifications qu'en a donné le client. Vous trouverez une description beaucoup plus complète ici.
Bref, c'est génial, c'est simple à utiliser... mais c'est extrêmement difficile à utiliser correctement. Et c'est catastrophique si c'est mal mal utilisé ! Pourquoi ?
Behat a deux côtés : un côté fonctionnel (rédacteur), rédigé avec la syntaxe de Gherkin, un côté "développeur", en PHP.
De ce que je vois, le plus souvent le fonctionnel (au choix) :
De ce que je constate, le développeur (au choix) :
Bon, le constant est sévère, mais je généralise bien sûr. Cependant il est très difficile d'échapper à ça.
Je passe aux exemples, tirés d'un code vu ce matin même.
Prenons ce bout de fonctionnalité que j'ai reçu comme spécification :
Bon, ça marche. Mais quand on y regarde plus près :
Bref, le test va rapidement devenir obsolète.
Il est difficile dans ce cas de voir comment s'abstraire des données (liaison id et task). Après réflexion, on peut suggérer d'évoluer vers ceci :
On a donc opéré des modifications afin de rendre le test indépendant du jeu de données ou de l'interface de l'application.
Ce que je dis souvent, c'est que, en théorie, un test de comportement est valide quelque soit le support : que l'on passe d'un site web à une application mobile, le changement de support ne change pas la fonctionnalité ou les scénarios ! Ca ne change que leur implémentation.
On pourra certainement trouver encore à redire, mais la fonctionnalité, telle qu'elle est décrite, est désormais valable quelque soit son implémentation technique. Seul son comportement est ici spécifié. Elle a donc une forte probabilité d'être viable et pertinente dans le temps.
On a vu un exemple de fonctionnalité à risque. Passons de l'autre côté et mettons-nous du point de vue du développeur. De la même façon, voici une implémentation possible :
Note : en l’occurrence, la liste des tâches n'est possible dans l'application qu'après avoir effectué une recherche.
On constate différente choses :
L'implémentation fonctionne, mais est peu viable dans le temps, et surtout on a perdu du temps pour l'écrire (c'est fastidieux de devoir manipuler le navigateur à la main).
Là où Behat est fort, c'est qu'il nous permet, en PHP, de faire comme si on écrivait des étapes de scénario "à la main". Ca fait gagner un temps monstre et permet de réutiliser les définitions existantes :
Pour s'aider, le développeur peut s'appuyer (si tout se passe bien) sur la personne qui a rédigé le scénario, qui l'aidera à découper sa définition en différentes étapes.
Attention, contrairement au scénario Gherkin, ce code peut être amené parfois à évoluer. Par exemple, si on ajoute un scénario pour la recherche de tâche, avec cette étape :
On pourra dès lors écrire :
Le développeur peut donc, sans architecture ou code complexe, mais simplement en utilisant les objets Etapes fournis par Behat, organiser ses définitions de façon à les rendre réutilisables.
Bref, ça semble évident, mais quand on fait du BDD... et bien il faut se focaliser le le Comportement. Ce n'est pas facile, et contre intuitif pour beaucoup de monde. Toutefois, le rédacteur du test peut s'aider de la structure de la fonctionnalité (comment la décrire, qui y participe, quels en sont les bénéfices, puis quels cas d'utilisation je peux en donner).
En d'autres mots, le "rédacteur" ne doit pas s'appuyer sur ce qu'il connaît de son application (emplacement, design...), mais sur la vision du produit (comment ça se passe ? Avec quel gain pour l'utilisateur ?). En clair :
Le rédacteur ne doit pas s'appuyer sur ce qu'il connaît de son application mais sur la vision du produit
Le développeur, lui, doit prendre l'habitude de ne pas se lancer tête baissée dans le code, au risque de consacrer trop de temps et d'énergie à l'utilisation de Behat. Certes il doit écrire ce code, mais il ne code plus pour interagir avec un autre code (comme lorsqu'il le fait pour un test unitaire par exemple), mais pour interagir avec un produit. En clair :
Le développeur n'interagit plus avec du code mais avec un produit
Ceci dit, félicitations d'avoir lu ce billet jusqu'au bout :-) .
Je ne prétend pas avoir le recul suffisant, mais je crois que ces constats s'appliquent généralement. C'est le cas pour vous aussi ? Vous avez vu d'autres écueils courants ? Ou au contraire, pour vous tout a roulé tout de suite ?
© Jean-François Lépine, 2013 - 2024