Le Behaviour-driven development (BDD ou développement dirigé par le comportement) est une méthodologie « extérieur-intérieur ». Il démarre à l' extérieur en identifiant les produits métiers puis pénètre dans les fonctionnalités (« features ») pour déterminer qui réalise ces produits. Chaque fonctionnalité est capturée dans une « story » qui définit la portée de cette fonctionnalité en même temps que les critères d'acceptation. Cet article est une introduction à l'approche BDD qui définit et identifie les histoires et leurs critères d'acceptation.

Ce qui suit est la traduction de l'article de Dan North : http://dannorth.net/whats-in-a-stor..., publiée ici avec son aimable autorisation.

Les termes fréquemment usités dans le domaine seront également signalés en anglais.

Introduction

La livraison de code consiste à écrire du code qui produit des résultats métiers. Cela semble évident, mais souvent des facteurs politiques ou environnementaux nous conduisent à l'oublier. Parfois, la livraison de code peut sembler ne consister qu'à réaliser des rapports optimistes permettant de s'assurer de la bonne humeur des responsables projet ou juste à simplement maintenir les gens occupés pour garantir de conserver les effectifs existant, mais c'est un autre sujet.

En général, les attendus métiers sont trop génériques pour pouvoir être utilisés directement pour écrire du code (où commencer à coder quand l'attendu est « économiser 5% de mes frais de fonctionnement »?), aussi nous avons besoin de définir des exigences à un niveau intermédiaire afin de pourvoir faire le travail.

Le Behaviour-driven development (BDD) prend le parti que vous transformez simplement et efficacement une idée d'exigence en code implémenté, testé et prêt pour la production tant que les exigences sont suffisamment spécifiques pour que tout le monde comprenne de quoi il retourne. Pour ce faire, nous avons besoin d'un moyen de décrire les exigences de telle sorte que tout le monde – les fonctionnels, les analystes, les développeurs et les testeurs – ait une compréhension commune de la portée du travail. A partir de là, ils peuvent se mettre d'accord sur une définition commune de « terminé » (« done ») et nous échappons aux pièges mentaux du découragement (« gumption traps ») du « ce n'est pas ce que j'avais demandé » et « j'ai oublié de vous dire quelque chose ».

Ceci, alors, est le rôle de l'histoire (« Story »). Elle doit être une description d'une exigence et du bénéfice métier associé assortie d'un ensemble de critères grâce auxquels on pourra s'accorder sur le fait que l'exigence est satisfaite, donc que le travail spécifié est terminé (« done »). Ceci constitue une définition plus rigoureuse que celle que l'on trouve dans d'autres méthodologies où elle est diversement décrite comme « la promesse d'un dialogue » ou « la description d'une fonctionnalité ». (Une histoire BDD peut aussi facilement décrire une exigence non fonctionnelle du moment que le travail peut être cadré, estimé et validé par tous).

La structure d'une histoire

Le BDD fournit une structure pour une histoire. Ce n'est pas obligatoire – vous pouvez utiliser un format d'histoire différent tout en continuant à faire du BDD – mais je la présente ici parce qu'elle a prouvé qu'elle fonctionne sur de nombreux projets de tous types et de toutes tailles. A la fin, votre histoire doit contenir tous les éléments décrits dans le modèle. Le modèle d'histoire ressemble à ce qui suit :

  Titre (une ligne décrivant l'histoire)
  
  Narration :
  En tant que {rôle}
  Je veux {une fonctionnalité}
  De telle sorte que j'obtienne {un bénéfice}
  
  Critères d'acceptation : (présentés sous forme de scénarios)
  
  Scénario 1 : Titre
  Étant donné {contexte}
     Et {un contexte de plus}...
  Quand {événement}
  Alors {résultat}
     Et {autre résultat}...
  
  Scénario 2 : ...

soit, en langue de Shakespeare :

  Title 
  
  Narrative :
  As a {role}
  I want {feature}
  So that {benefit}
  
  Acceptance Criteria
  
  Scenario 1 : Title
  Given {context}
     And {context}...
  When {event}
  Then {outcome}
     And {outcome}...

Raconter l'histoire

Une histoire doit être le résultat d'une conversation impliquant plusieurs personnes. Un analyste métier (un fonctionnel) parle à un responsable fonctionnel (business stakeholder, en fait, il doit être la personne qui a un intérêt réel à cette fonctionnalité, si bien qu'il peut s'agir aussi bien d'un utilisateur fonctionnel, d'un expert juridique ou d'un responsable SSI concerné par l'histoire) d'une fonctionnalité ou d'une exigence et l'aide à la cadrer en tant que narration d'une histoire. Puis un testeur vient aider à définir la portée de l'histoire – sous forme de critères d'acceptation – en déterminant les scénarios indispensables et ceux qui sont moins utiles. Un représentant technique va fournir une estimation approximative du volume de travail nécessaire pour cette histoire et proposer des approches alternatives. De nombreuses idées formidables viennent aussi bien des personnes qui les développent que des personnes les ayant demandés initialement.

C'est à l'évidence un processus itératif. Le responsable fonctionnel aura une idée de ce qu'il veut mais ne saura habituellement pas à quelle charge de travail cela correspond ni comment ce travail sera réparti. Avec l'aide d'experts techniques et de test, il va comprendre les compromis coûts/bénéfices de chaque scénario et se faire une opinion sur leur nécessité. Bien sûr, ceci est mis en balance avec d'autres exigences : est-il mieux de couvrir davantage de cas limite dans cette histoire ou de les déplacer dans une autre ?

Quelquefois, l'équipe de développement n'en sait tout simplement pas assez pour être capable de faire une estimation approximative. Dans ce cas, elle peut décider de mener un travail d'analyse complémentaire, souvent dénommé exploratoire (« spike ») afin d'en savoir plus sur les exigences (plus dans un futur article).

Les caractéristiques d'une bonne histoire.

En nous appuyant sur l'exemple de l'article Introducing BDD, examinons les exigences relative au retrait d'argent dans un distributeur :

  Histoire : le détenteur d'un compte retire du liquide
  
  En tant que détenteur de compte
  Je veux retirer du liquide à un distributeur
  De telle sorte que j'obtienne de l'argent quand la banque est fermée
  
  Scénario 1 : le compte est suffisamment crédité
  Étant donné un solde de 100€
     et que la carte est valide
     et que le distributeur contient assez d'argent
  Lorsque le détenteur du compte demande 20€
  Alors le distributeur va donner 20€
     et le solde doit être de 80€
     et la carte doit être rendue 
  Scénario 2 : le compte est insuffisamment crédité
  Étant donné un solde de 10€
     et que la carte est valide
     et que le distributeur contient assez d'argent
  Lorsque le détenteur du compte demande 20€
  Alors le distributeur ne donne pas d'argent
     et le distributeur indique que le solde est insuffisant
     et le solde doit être de 10€
     et la carte doit être rendue
  
  Scénario 3 : la carte a été invalidée
  Étant donnée que la carte a été invalidée
  Lorsque le détenteur du compte demande 20€
     alors le distributeur doit garder la carte
     et le distributeur doit indiquer que la carte a été retenue
  
  Scénario 4 : le distributeur n'a pas de fonds suffisants
  ...

Comme vous pouvez le voir, il y a de nombreux scénarios à considérer, certains relatifs au solde du compte, d'autre à la carte et encore d'autres relatifs au distributeur lui-même. Examinons l'histoire pour déterminer ce qui est bon.

Le titre doit décrire une activité

Le titre de l'histoire, « le détenteur d'un compte retire du liquide », décrit une activité que le détenteur du compte veut réaliser. Jusqu'à ce que nous implémentions cette fonctionnalité, le détenteur du compte ne pourra pas retirer de liquide d'un distributeur. Une fois livrée, il pourra. Ceci donne un point de départ évident pour déterminer à quoi ressemblera « réalisé » (« done »).

Si nous avions eu un titre tel que « gestion du compte » ou « comportement du distributeur », nous aurions du creuser plus profondément pour comprendre à quel moment nous pouvons considérer que nous avons fini et les limites auraient été un peu plus floues. Par exemple, « gestion du compte » pourrait intégrer l'application d'un prêt et « comportement du distributeur » pourrait inclure le changement du code d'identification de la carte. Le titre de l'histoire doit toujours décrire l'utilisation réelle du système par un utilisateur.

La narration doit inclure un rôle, une fonctionnalité et un bénéfice

Le modèle « En tant que {rôle} Je veux {une fonctionnalité} de telle sorte que j'en tire {un bénéfice} » ( “As a {role} I want {feature} so that {benefit}“ ) possède de nombreux avantages. En indiquant le rôle dans la narration, vous savez à qui parler au sujet de cette fonctionnalité. En indiquant le bénéfice attendu, vous forcez le rédacteur de l'histoire à se demander pourquoi il veut une fonctionnalité.

Il devient intéressant de découvrir que la fonctionnalité ne produit pas le bénéfice qui lui a été attribué. Cela signifie habituellement qu'il vous manque une histoire. Il existe une histoire dotée de la fonctionnalité actuelle qui fournit un bénéfice différent (et qui reste de ce fait utile) ainsi qu'une histoire cachée pour laquelle vous avez besoin d'une fonctionnalité différente pour fournir le bénéfice attendu.

L'histoire exemple nous indique qu'il y a un Détenteur de compte qui est intéressé par la fonctionnalité délivrée, de telle sorte que nous savons où commencer à chercher ce qu'elle doit faire.

Le titre du scénario doit indiquer ce qui est différent

Vous devez être capable d'aligner côte à côte les scénarios et de dire en quoi ils diffèrent en n'utilisant que leurs titres. Dans notre exemple, vous pouvez voir que les descriptions des scénarios ne signale que ce qui diffère entre chaque scénario. Vous n'avez pas besoin de dire : « un détenteur de compte retire du liquide d'un compte dont le solde est insuffisant et est averti qu'il sera impossible de compléter la transaction ». Il est évident à partir du titre de savoir si c'est le scénario qui vous intéresse en le comparant aux autres.

Le scénario doit être décrit en terme de pré-requis, d'événement et de résultats (Givens, Events et Outcomes)

C'est l'unique changement le plus puissant que j'ai constaté dans les équipes adoptant le BDD. En poussant simplement les utilisateurs métier, les analystes, les testeurs et les développeurs à adopter ce vocabulaire “étant donné/quand/alors”, ils vont constater qu'un monde d'ambiguïtés va disparaître.

Tous les scénarios ne sont pas aussi simple. Certains sont mieux représentés par une suite d'événements décrits par : étant donné {un contexte} quand {Je fais quelque chose} alors {ceci ce produit} quand {je fais une autre chose} alors {cette nouvelle chose se produit} et ainsi de suite. Un exemple est le site web style assistant (wizard) où vous progressez étape par étape via une suite d'écrans pour construire un modèle de données complexe. C'est parfaitement adapté d'intercaler des suites d'événements et de résultats tant que vous gardez l'habitude de penser en ces termes.

Un comportement émergent intéressant est que la qualité de la conversation change. Vous allez rapidement découvrir que vous avez oublié un pré-requis sous-entendu («Évidemment que le compte est à découvert ») ou oublié de vérifier un résultat («Naturellement que le détenteur du compte récupère sa carte »). J'ai observé ceci sur un projet précis sur lequel le chef de projet me disait que cela aurait du sens que les analystes et les développeurs parlent sur des objectifs croisés mais ne pouvait pas trouver un moyen de le leur démontrer. En quelques jours d'introduction du vocabulaire étant donné/quand/alors, il a pu constater une amélioration très significative de la qualité de leurs interactions.

Les étant donné doivent définir entièrement, et pas davantage que cela, le contexte nécessaire

Chaque « étant donné » additionnel ajoute de la distraction ce qui rend difficile à quelqu'un examinant l'histoire pour la première fois – qu'il soit du côté technique ou fonctionnel – de comprendre ce qu'il a besoin de savoir. De la même façon, tout étant donné manquant constitue de vraies hypothèses. Si vous pouvez obtenir un résultat différent avec les étant donné fournis, alors il doit manquer quelque chose.

Dans l'exemple, le premier scénario indique quelque chose sur le solde du compte, la carte et le distributeur lui-même. Tout ceci est indispensable pour pleinement définir le scénario. Dans le troisième scénario, nous ne disons rien sur le solde du compte ni même si le distributeur possède de l'argent. Ceci implique que la machine retiendra la carte quel que soit le solde du compte et quel que soit l'état du distributeur.

L'événement doit décrire la fonctionnalité

L'événement lui-même doit être très simple, typiquement seulement un unique appel au code de production. Comme discuté ci-dessus, certains scénarios sont plus compliqués que cela, mais la plupart des scénarios d'une histoire vont tourner autour d'un unique événement. Ils vont différer seulement par le contexte (les étant donné) et les résultats correspondants attendus.

L'histoire doit être suffisamment petite pour correspondre à une itération

Il n'existe pas de règles compliquées et rapides sur la façon de parvenir à ce résultat aussi longtemps que vous la divisez en morceaux démontrables. En général, si elle a plus de 5 ou 6 scénarios, une histoire peut probablement être décomposée en regroupant des scénarios similaires.

Nous ne pouvons pas dire à partir de l'exemple du distributeur combien de scénarios supplémentaires il y a pour cette histoire mais je suspecte qu'il doit y en avoir plusieurs. Nous avons essentiellement trois « parties mobiles » dans cette histoire, à savoir le « solde », « l'état de la carte » et « l'état du distributeur ». Nous pourrions aller plus en détail avec la carte de crédit : que se passe-t'il si elle périmée, aussi je ne peux pas récupérer d'argent mais le distributeur va-t'il me la rendre ? Que se passe-t'il si le distributeur tombe en panne au milieu de la transaction ? Que se passe-t'il si mon compte a une autorisation de découvert ?

Il peut être préférable de diviser l'histoire en plusieurs histoires plus petites :

  • Le détenteur du compte retire du liquide (suppositions: le distributeur est en service et la carte est valide)
  • Le détenteur du compte retire du liquide avec une carte invalide (suppositions: le distributeur est en service)
  • Le détenteur du compte retire du liquide d'un distributeur en panne (suppositions: la carte est valide)

Bien que ceci puisse sembler artificiel, cela vous permet de montrer les progrès en terme de progrès et vous donne davantage de données à suivre. La chose importante est de toujours diviser l'histoire selon l'axe métier via les scénarios (et de rendre explicites les hypothèses) plutôt que selon l'axe technique (par exemple, réaliser quelque chose sur la base de données durant l'itération et quelque chose sur l'IHM lors de la suivante). Ainsi, les fonctionnels peuvent voir des progrès démontrables avec leurs propres termes plutôt que vous croire sur parole.

En quoi cela diffère-t'il des cas d'utilisation (Use Cases) ?

Il y a cas d'utilisation et cas d'utilisation. Je suis un grand fan de la façon dont Alistair Cockburn décrit les cas d'utilisation (par opposition aux versions sur-élaborées que j'ai rencontrée sur des projets RUP en cascade). Ceci dit, je n'ai pas beaucoup d'expérience sur les projets dirigés par les cas d'utilisation, je laisse donc aux autres le soin de réaliser les comparaisons.

Je suis évidemment d'accord avec son processus débutant au niveau de précision le plus grossier (d'un résultat ou objectif) pour atteindre le niveau de précision le plus fin amenant le plus de scénarios d'exception au fur et à mesure. Avec BDD, cela signifie démarrer avec les résultats métier attendus et travailler à partir de zones fonctionnelles de haut niveau pour descendre à celui d'histoires spécifiques dotées de critères d'acceptation.

En réalité, le processus que vous utilisez pour identifier et élaborer vos exigences n'a pas d'importance. Vous pouvez écrire des documentations de spécifications si cela vous aide à organiser votre pensée. Ce qui ne convient pas, c'est de transmettre ces documents comme s'ils enfermaient toute votre pensée, car ce n'est pas le cas. A la place, vous devrez mettre de côté votre document d'exigences ou pile de use cases et commencer à définir des histoires à partir des bénéfices métier, assuré que vous êtes de savoir que votre dur labeur a signifié que vous avez toutes les réponses dans votre tête – ou du moins une compréhension suffisamment bonne pour schématiser le travail tel que vous le concevez actuellement.

Résumé

Le développement Behaviour-driven utilise une histoire comme unité de base des fonctionnalités, et, de ce fait, des livraisons. Les critères d'acceptation sont une part intrinsèque de l'histoire – dans le sens qu'ils définissent la portée de son comportement et nous donne une définition partagée de « terminé ». Ils sont également utilisés comme une base d'estimation quand nous en arrivons à faire notre planification.

Plus important, les histoires sont le résultat de conversations entre les fonctionnels, les analystes métier, les testeurs et les développeurs. BDD concerne au moins autant les interactions entre les différents intervenants du projet que les résultats du processus de développement.