BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles Interviews Croisés : Couverture de Code, TDD et BDD

Interviews Croisés : Couverture de Code, TDD et BDD

Au cours des derniers mois plusieurs discussions en ligne ont eu lieu à propos de « test first » (tester d'abord) vs « test last » (tester ensuite), la couverture de test et si BDD n'était que du TDD. InfoQ a demandé à des experts renommées de TDD et BDD de nous donner leurs points de vue sur l'utilisation de TDD, BDD, et la couverture par les tests.

Experts interrogés :
JB Rainsberg - Consultant et expert en TDD, son blog The Code Whisperer
Dan North - Spécialiste en Technologie Lean au DRW Trading Group, a inventé le terme de Behaviour Driven Development (BDD)
Gojko Adzic - Consultant, auteur de « Specification by Example » et « Bridging the Gap Communication »
Ron Jeffries - Consultant indépendant dans les méthodes Agile et XP, animateur du projet XP
Steve Freeman - formateur et consultant Agile, auteur de « Growing Object Oriented Software, Guided by Tests »

Questions posées :
1. D'après vous, quels sont les critères qui devraient guider la décision d'utiliser TDD et / ou BDD (ou aucun des deux) pour le développement d'un projet donné ?
2. Pour généraliser il semble que l'on pourrait comprendre TDD = tests unitaires et BDD = tests d'acceptation (indépendamment des outils). Dans quelle mesure est-ce correct, et où peuvent s'insérer dans ce schéma d'autres types de tests, par exemple les tests de composant ou les tests d'intégration ?
3. Au fil des ans TDD a été considéré comme une discipline de conception, une discipline pour tester, ou comme un outil de communication. De quelle manière ces objectifs distinctes influent-ils la conception des tests en TDD, et sur l'évaluation de leur valeur présente ou futur ?
4. Recommandez-vous quelques critères initiaux pour déterminer le ratio des tests unitaires par rapport aux tests d'intégration et aux tests d'acceptation, en prenant en compte l'automatisation et les coûts de maintenance ?
5. Systèmes critiques exclus, il semble y avoir aujourd'hui un consensus pour dire qu'une couverture par les tests de 100% ne devrait pas être un objectif ou un idéal en soi lors du développement d'un logiciel. Pensez-vous que les efforts portés sur le taux de couverture du code testé peut promouvoir des tests plus ciblés et / ou plus efficaces ?
6. TDD, BDD, ATDD, Testé d'Abord, Spécification par l'Exemple, etc ... peuvent prendre différentes significations en fonction des personnes et cela peut prêter à confusion. Avons-nous oublié un langage ubiquitaire pour décrire nos méthodologies de développement logiciel et pour développer une compréhension partagée des bonnes pratiques ?
7. Un dernier mot sur ces sujets ?

InfoQ : D'après vous, quels sont les critères qui devraient guider la décision d'utiliser TDD et / ou BDD (ou aucun des deux) pour le développement d'un projet donné ?

JB : Je me sens mal à l'aise pour donner une réponse générale sur ce sujet, permettez-moi de décrire pourquoi et quand j'utilise TDD / BDD.

J'ai commencé à pratiquer TDD parce que je cherchais un moyen d'arrêter de patauger dans les erreurs (défauts ou bugs). Le nombre d'erreurs que je faisais dans mes programmes m’empêchait d'avoir la satisfaction d'un travail accompli : peu importe combien j'en avais fait, je ne me suis jamais senti proche du travail bien fait. J'ai remarqué alors que si j'avais testé mon propre code, j'aurai trouvé la plupart des idioties, des fautes simples, et les aurai corrigées moi-même. Je ne cherchais pas tant à éviter d'avoir l'air stupide, mais plutôt à éviter un faux sentiment d'avoir terminé mon travail. Cela m'a aidé, et après quelques années j'ai commencé à réaliser que TDD m'aidait non seulement à éviter des erreurs lors de l'exécution du code, mais aussi à éviter des fautes dans la conception. Quand j'ai appris BDD, j'ai fini par comprendre plus tard que cela m'avait aidé à éviter des mauvais choix dans les fonctionnalités et leur implémentation. Au fil des années, j'ai réalisé que les erreurs me coûtaient plus de temps, d'efforts et d'énergie que de faire du bon travail, de sorte que TDD et BDD sont devenus des pratiques de base pour moi.

Pour revenir à la question, j'encourage les gens à expliquer pourquoi ils veulent faire du TDD, et de le faire pour ces raisons. Au-delà des raisons typiques pour pratiquer TDD / BDD - meilleures conceptions, moins de défauts, fonctionnalités utiles, moins d'efforts gaspillés - j'encourage les gens à s'interroger sur les raisons personnelles pour pratiquer TDD / BDD et de se concentrer sur celles-ci. Je cherchais à être plus confiant dans mon sentiment que j'avais fini un travail donné, sinon cela me causait trop d'inquiétude. Je pense que ces raisons diffèrent énormément d'une personne à une autre.

Dan : Tout d'abord permettez-moi de donner de vagues définitions. TDD est une technique de programmation qui demande à un programmeur de réfléchir à son code à partir de la perspective d'un autre bout de code qui va l'utiliser, ce qui favorise la conception émergente. Vous écrivez un test pour décrire la façon dont le prochain bloc de code sera utilisé, alors vous écrivez le code pour faire que ce test passe. Cette technique est le domaine exclusif des programmeurs et quand elle est appliquée correctement (je vais le développer dans un instant), elle dispose d'un certain nombre d'avantages subtils. L'écriture des tests vous aide à comprendre le domaine métier pour lequel vous travaillez et peut vous aider à nommer les choses. Un test peut exposer une lacune dans la compréhension ("Que pensez-vous qu'il est censé faire dans ce cas?") et bien sûr une suite de tests automatisés peut aider à identifier les défauts de régression.

Je pense que la décision d'utiliser ou non TDD pour un projet donné ne se pose jamais. On peut utiliser TDD dans presque n'importe quel projet. Cependant, je dirais que c'est à utiliser seulement si les programmeurs le trouvent utile. Il y a d'autres moyens que TDD pour faire de la conception, de l'exploration et de la modélisation d'un domaine, et de réduire les risques de régression. Parfois, c'est le moyen le plus efficace et parfois non. Cela dit, je pense que TDD est une technique utile, je crois que tous les programmeurs devraient le connaître et savoir le pratiquer. Je dirais la même chose du refactoring : ne pas s'y connaître n'est pas excusable, et c'est l'expérience qui peut vous aider à choisir quand et où l'appliquer, et quand faire autre chose.

BDD est une méthodologie de développement, plus proche dans la forme à celle ressemblant à l'eXtreme Programming que de la pratique de TDD. Il est un moyen d'obtenir des parties prenantes et des prestataires avec des perspectives différentes sur la même maquette, la valorisation des mêmes fonctionnalités et les mêmes attentes. Si vous n'avez pas ce problème à résoudre, BDD n'est peut-être pas pour vous. Certes, je n'en ai pas eu besoin récemment, parce que j'ai été dans des équipes très petites avec un retour des intervenants très rapide, donc l'impact d'une mauvaise prestation est considérablement réduit. Il se résumait généralement à "Pouvez-vous effectuer ce changement s'il vous plaît ?" ou "Ce n'est pas ce à quoi je pensais. Voici un exemple."

BDD commence par un objectif d'entreprise et décrit comment cet objectif donne lieu à des fonctionnalités et des « stories ». BDD conditionne la structure de vos critères d'acceptation et la façon dont vous les transformez en des tests automatisés qui définissent le comportement du code. La décision d'investir dans BDD est donc prise au niveau du projet (bien que sans doute on puisse appliquer BDD sur un sous-ensemble du projet), et devrait impliquer l'ensemble de l'équipe.

Je dirais que tout programmeur, ou paire de programmeurs, a le droit de livrer des logiciels comme il le souhaite, à condition qu'il respecte l'équipe et la base de code. Si il souhaite utiliser TDD, il devrait être autorisé et même encouragé à le faire. Si il veut faire autrement cela devrait être possible également, tant qu'il a l'accord de ses coéquipiers.

Gojko : Cela dépend de votre définition de ces sujets. Il semble qu'au cours des dernières années, le sens de TDD a été réduit à seulement inclure la conduite de conception technique avec les tests unitaires, et que BDD est devenu le fourre-tout pour la conduite de l'implémentation des fonctionnalités métier avec des exemples et des tests orientés métier. En appliquant la terminologie du diagramme des Quadrants du Test Agile de Brian Marick tel que publié dans Agile Testing par Lisa Crispin et Janet Gregory, cela nous donnerait TDD dans le quadrant 1 et BDD dans le quadrant 2. Je ne suis pas vraiment d'accord avec cela, mais étant donné la façon dont vous avez posé la question je suppose que votre définition de TDD exclut BDD et inversement. En supposant cette relation, je distinguerai trois cas :

  • Le projet est-il ponctuel et destiné à rester dans les oubliettes ? Est-ce un défi technique visant à lever une incertitude technique, en aidant l'équipe à découvrir à partir d'un point de vue technique ce qu'ils veulent vraiment faire ? Dans ce cas, avoir un grand nombre de tests automatisés est sans doute inutile, et l'équipe s'est probablement fixé un petit nombre de cas d'utilisation relativement simples. Écrire des tests techniques par avance peut être un problème parce que nous ne connaissons pas vraiment les contraintes techniques sous-jacentes. J'écrirai probablement quelques tests directeurs techniques, mais je ne serai pas dogmatique pour prendre chaque décision de conception avec des tests techniques / unitaires. C'est comme cela que ça fonctionne dans les grands systèmes de test que Steve Freeman et Nat Pryce ont écrit dans Growing Object Oriented Software.
  • Est-ce la clé de la complexité d'un projet technique ? Connaissons-nous ce que nous souhaitons atteindre techniquement, sans risques ou incertitudes métier ? Toutes les personnes qui travaillent sur un projet technique, peuvent-ils lire le code ? Par exemples la construction d'un framework web, une plate-forme de base de données, un système de file d'attente, ou une plate-forme de déploiement dans les nuages. La plupart des projets Open-Source sont dans cette catégorie. Si oui, le TDD technique est probablement suffisant – je piloterai les scénarios métier et la conception technique en utilisant un outil de test unitaire. Je continuerai à utiliser des exemples sur les tableaux blancs pour assurer une compréhension commune (partie centrale de BDD), mais je ne reperdrai pas du temps avec la mise en œuvre de ces exemples dans une spécification exécutable / un outil d'automatisation non technique tel que Cucumber.
  • Y a t-il également de la complexité métier, un risque d'exigences mal définies qui doit être communiqué à des personnes qui ne savent pas lire le code du langage de programmation ? Si c'est le cas, je sépare les problèmes. Utiliser des exemples pour explorer les besoins métiers et s'assurer d'une compréhension partagée entre les gens du métier et les prestataires, la construction du cahier des charges à partir de ces exemples et automatiser ces exemples dans une documentation vivante à l'aide de Cucumber, FitNesse ou similaire, puis piloter la conception de mon code à l'aide des tests unitaires.

Ron : J'utiliserai ces approches pour chaque projet que j'ai réalisé dans mon demi-siècle de développement logiciel. Gardez à l'esprit que je ne les ai pas inventé : je suis juste un étudiant de la première heure. Ils m'ont donné une confiance qu'aucune autre approche ne m'a jamais donnée. Ils ont réduit largement le nombre de mes erreurs. Et ils m'ont permis d'améliorer la conception parce que je comprenais mieux ce qu'elle devait être.

C'est assez difficile à battre.

Steve : Avez-vous besoin d'écrire des tests pour votre système ? Si oui, alors pourquoi ne pas les écrire en premier afin qu'ils soient effectivement faits, et afin que vous puissiez voir ce qui accroche pour rendre leur réalisation plus facile ? Vous avez peu de chance de prévoir tous les tests qui doivent être écrits, il est donc plus facile de les faire au fur et à mesure.

InfoQ: Pour généraliser il semble que l'on pourrait comprendre TDD = tests unitaires et BDD = tests d'acceptation (indépendamment des outils). Dans quelle mesure est-ce correct, et où peuvent s'insérer dans ce schéma d'autres types de tests, par exemple les tests de composant ou les test d'intégration ?

JB : Je préfère séparer les deux de cette façon : TDD me donne un feedback sur ma conception, tandis que BDD me donne un feedback sur ma compréhension du produit que nous voulons construire. Alors que je débutais la pratique de TDD en tant que technique de test, j'ai appris à voir TDD comme une technique de conception, et après comme une technique pour apprendre en profondeur les principes d'une bonne conception modulaire. J'ai commencé à pratiquer BDD comme un moyen de me rappeler de voir le produit du point de vue des utilisateurs finaux et des intervenants métiers, mais j'ai ensuite appris à voir BDD comme une technique pour améliorer la communication entre les gens du métier et les développeurs. Comme vous pouvez le voir, les tests jouent juste un petit rôle, qui reste cependant significatif.

Comme je ne considère pas TDD et BDD comme des techniques de test, pour moi la stratégie des tests est indépendante de TDD et BDD. Que je choisisse de faire du TDD ou du BDD ou non, je m'attends à penser microtesting, tests système et tests d'utilisabilité sur l'ensemble du projet.

Dan : Il s'agit d'une circonstance malheureuse de l'histoire. En fait, TDD et BDD sont les deux à la fois, et plus encore. Kent Beck décrit TDD dans Extreme Programming Explained - et plus tard dans son livre TDD - de la même manière que Nat Pryce et Steve Freeman le décrivent dans Growing Object Oriented Software, à savoir que cela fonctionne à plusieurs niveaux de granularité. Vous écrivez des tests fonctionnels au niveau utilisateur ou des tests unitaires de bas niveau pour la même raison : illustrer la façon dont vous voulez que le code fonctionne. TDD est dans l'intention plutôt que dans l'activité : Vous pouvez écrire des tests automatisés pour la seule raison
d'augmenter votre couverture de test. Ce n'est pas du TDD. De même, vous pouvez piloter par les tests la conception d'exigences non-fonctionnelles comme la concurrence, la latence, le basculement ou le débit.

La distinction dans BDD entre le niveau-utilisateur et le niveau-code des tests est plus explicite. Au niveau utilisateur, les tests prennent la forme de scénarios qui sont structurés d'une manière particulière qui se prête à la clarté et à l'automatisation. De même, les étapes qui les composent peuvent être réutilisées dans d'autres scénarios. Les tests au niveau code sont appelés exemples (ou spécs, mais je ne suis pas un fan de cette appellation) et sont plus proches de ce que les gens pensent être des tests TDD. Au fil du temps cela à conduit à l'émergence de différents outils, avec des outils langage-agnostique comme Cucumber pour les scénarios au niveau-utilisateur et des outils langage-spécifique pour les exemples au niveau code comme RSpec, NSpec et d'autres. Ma propre expérience a été d'utiliser ceux avec lesquels l'équipe est à l'aise, donc la plupart du code de BDD que j'ai écrit utilise le vénérable JUnit avec la bibliothèque de matcher Hamcrest de jMock. Je suis actuellement entrain d'utiliser py.test pour Python et nodeunit pour node.js, qui sont semblables dans le style à JUnit, même si des frameworks "style-BDD" existent pour les deux. C'est à vous de décider comment est structuré un test, comme pour le code.

Gojko : Encore une fois cela dépend de votre définition de TDD, de BDD et des concepts associés. Ma compréhension du travail de Kent Beck est que les tests métiers et les tests unitaires appartiennent tous à TDD. Ma compréhension de l'approche de Nat Pryce et de Steve Freeman dans Growing Object Oriented Software, c'est que TDD comprend des tests du système, des tests de composants et des tests unitaires. La façon dont j'explique les choses dans Specification by Example est qu'une documentation bien vivante se décompose en concepts métiers, et là où vous automatisez est une question de couverture des risques - un exemple peut être validé par l’exécution d'une seule méthode java si le plus gros des risque est là, ou par la réalisation d'un système grandeur nature avec 30 services Web et 100 bases de données, si le risque est ici.

Ron : BDD a commencé à être une variante de TDD. Maintenant, pour des gens comme Chris Matts et Liz Keogh et d'autres, et dans la mesure où je comprends vraiment ce qu'ils font, BDD est devenue une description du besoin et des tests d'acceptation.

Quant aux autres formes de tests, ils peuvent bien sûr toujours être utiles. Je voudrais en particulier ajouter à votre liste les tests d'expérience de l'utilisateur. Comme pour les test de composant et les tests d'intégration, les meilleurs projets Agile utilisent l'Intégration Continue, de sorte que l'on voit rarement les composants séparés les uns des autres, et le système intégré est supporté par le poids des tests. Souvent, ces anciennes distinctions embrouillent, et on a à la place différentes suites de tests qui sont exécutées à intervalles différents, en réponse à divers événements, comme l'arrivée d'une nouvelle bibliothèque ou d'un composant, ou le déclenchement d'un nouveau build. Ces suites peuvent contenir toutes sortes de tests qui auraient été décrits une vingtaine d'années auparavant comme des tests unitaires, des tests d'acceptation, et ainsi de suite.

L'essentiel est de tester ce qui doit être testé, et de le tester autant que possible au plus près du moment de sa création, ou de son évolution. C'est de cette manière que nous pouvons prévenir la plupart des défauts et découvrir rapidement la majeur partie restante.

Steve : Ce n'est pas une distinction que je fais. Elle semble avoir été imposée sur la base d'un malentendu au sujet de TDD. Une question fondamentale dans TDD est: «Si cela fonctionne, comment pourrai-je le savoir ?" - Elle s'applique à tous les niveaux, y compris pour l'entreprise / l'organisation.

Je ne suis également pas convaincu que le découpage des tests en silos (en des suites distinctes et séparées) aide vraiment, l'idée est de construire un continuum de test qui donne confiance à l'équipe que le système fonctionne.

InfoQ : Au fil des ans TDD a été considéré comme une discipline de conception, une discipline pour tester, ou comme un outil de communication. De quelle manière ces objectifs distinctes influent-ils la conception des tests en TDD, et sur l'évaluation de leur valeur présente ou futur ?

JB : Cela dépend en grande partie de qui pratique TDD. Lorsque j'ai commencé à pratiquer TDD, mon intérêt principal résidait dans la discipline des tests, sans doute parce que je voulais améliorer spécifiquement ce point. Seulement après avoir considérablement réduit mes erreurs, j'ai remarqué que TDD guidait l'amélioration de ma conception. Tout ceci conduit à une perception très personnelle de la valeur présente des tests écrits tout en pratiquant TDD : chacun trouvera probablement les avantages qu'il recherche.

Je trouve la valeur présente des tests beaucoup plus élevées que leur valeur future. J'ai même eu comme idée de jeter les tests quelques mois après leur création, et de les réécrire seulement si je devais changer quelque chose, mais je ne l'ai jamais appliquée.

Je n'ai pas tiré beaucoup de bénéfices des tests que je n'ai pas écrits moi même ; je ne sais pas dans quelle mesure attribuer cela aux projets sur lesquels j'ai travaillé et dans quelle mesure l'attribuer au niveau général des développeurs. Je trouve cela troublant, car cela me fait penser aux entrepreneurs qui visitant une maison commencent à dire du mal de ceux qui ont fait la rénovation précédente.

J'ai affirmé, et lu des affirmations, comme quoi les tests « style-TDD » agissent comme un pool de détecteurs de changement (pour employer le terme de Cem Kaner) afin de réduire le coût de la modification du code plus tard. J'ai vu ces avantages, même si je ne les ai jamais mesuré précisément. J'ai également entendu dire que les tests peuvent bien décrire le système / l'API à des gens qui ne le connaissent pas. Hélas, cet avantage reste pour moi la plupart du temps improbable.

Dan : TDD est une discipline de conception. Tout le reste est du bonus. Le mot "test" dans "piloté par les tests" (TDD = Test Driven Development ou Développement Piloté par les Tests) est malheureux. Les exemples-que-vous-écrivez-pour-décrire-un-comportement ne sont des tests qu'après coup. Durant tout le temps du codage, ils sont tout simplement des exemples de l'utilisation souhaitée. En conjonction avec les pratiques analogues à l'Intégration Continue, ces exemples deviennent une suite de tests de régression une fois que le code est écrit. Mais ils ne remplacent pas le besoin de tester avec des compétences spécifiques, par exemple à l'aide des tests exploratoires promus par Brian Marick et James Marcus Bach. Une autre caractéristique des tests TDD est leur déterminisme. C'est une force dans une suite de tests de régression, mais une faiblesse en ce qui concerne la découverte des recoins sombres. Les techniques de tests aléatoires peuvent débusquer des myriade de subtilités dans les systèmes complexes, on peut ensuite utiliser TDD pour les éliminer. Un bon exemple est l'outil QuickCheck en Haskell (et en Scala).

Quant à la communication, c'est l'un des principal objectif de TDD, en particulier être clair pour soi-même et avec les autres programmeurs sur l'intention du code. Dans mon article Introducing BDD, je décris comment il est utile de donner aux tests des noms qui révèlent ce pourquoi on les écrit, dans le cas contraire quand un test échoue, vous ne savez pas ce que cela veut dire. Vous devriez être capable de lire les tests TDD comme un récit, et les noms des tests devraient fournir un certain niveau de documentation fonctionnelle.

Gojko : Je pense que la réponse, comme souvent, réside dans l'équilibre de ces forces. Pour tirer le meilleur parti de TDD en tant que discipline, nous devons trouver un moyen de faire toutes ces choses. De bons tests unitaires pilotent la conception, mais nous aide aussi à lever d'importants problèmes techniques et de communiquer sur ce que le code est censé faire.

Ron : TDD utilise des tests, mais l'essentiel ce ne sont pas les tests. C'est une façon de développer un système de telle sorte que nous construisons, dans le même temps, un échafaudage de tests et le programme lui-même. TDD et les pratiques associées nous permettent de construire le système progressivement, fonction par fonction, en toute sécurité et en gardant le code vivant et malléable dès le début du projet et jusqu'à sa fin. Cela nous permet d'avoir une idée claire de ce qui a été vraiment réalisé, ce qui permet au Product Owner ou à la direction de prendre les meilleures décisions possibles pour l'étape suivante. Il limite considérablement le nombre de mauvaises nouvelles que nous obtenons à la fin de projets classiques, que ce soit par la découverte de code truffé de défauts, ou d'une conception qui s'est détériorée et que nous ne pouvons pas améliorer rapidement.

Je ne pense pas que ces objectifs soient «distincts». Le développement de logiciels bien fait exige l'intégration de nombreuses idées et exige que nous gardions de nombreux objectifs en équilibre. Nous ne recherchons à pas faire de compromis. Au contraire, nous voulons travailler de manière à ce que que tous les objectifs soient atteints, car cela nous permet de créer le meilleur produit possible et de la manière la plus rapide.

Steve : Je cherche à mettre l'accent sur l'aspect communication des tests (à tous les niveaux) car je trouve que cela mène à de meilleurs résultats pour les autres points. Par exemple, si je me concentre pour obtenir un test facile à lire, lorsque je tente de coincer une responsabilité inappropriée dans un objet, elle ressort.

Je vois beaucoup d'équipes avoir des suites de tests qui pourrissent dans un marécage ingérable ce qui ne fait que ralentir leur progrès. Le code d'un test a besoin de soins et d'attention, tout comme (et même peut-être plus que) le code de production, d'autant plus que de nouvelles compréhensions et de nouveaux concepts apparaissent et doivent être ajoutés dans le système.

InfoQ : Recommandez-vous quelques critères initiaux pour déterminer le ratio des tests unitaires par rapport aux tests d'intégration et aux tests d'acceptation, en prenant en compte l'automatisation et les coûts de maintenance ?

JB : Les équipes me contactent de temps en temps, quand ils ont passé 1 à 2 ans à pratiquer TDD et voient un déséquilibre dans le rapport coût / bénéfice des tests. Dans tous les cas, cela arrive quand ils essaient d'utiliser de trop gros tests (tests intégrations, des tests du système, des tests de bout en bout) pour vérifier de petites choses (le comportement détaillé d'objets individuels). Cela conduit à des suites de tests trop longues, des suites de test plus fragiles (une erreur signifie 23 échecs), et décourage généralement les programmeurs de les maintenir. Les tests pourrissent, et apportent plus d'inconvénients qu'ils n'aident.

Dans cette situation, je conseille généralement d'apprendre à écrire des micro-tests pour vérifier des « micro comportements », de combiner des tests de collaboration et de contrat pour vérifier une couche en la connectant uniquement à l'interface de la couche adjacente, et pas plus loin. Cela signifie s'éloigner des tests intégrés et de système pour vérifier ce que j'appelle « l'exactitude de base » - qui est, compte tenu du cas idéal et nominal, cet objet calcule t-il la bonne réponse ? C'est ce que je veux exprimer lorsque je dis "les tests intégrés sont une escroquerie".

Bien que les détails diffèrent d'un projet à un autre et d'une équipe à une autre, je recommande assez fréquemment aux programmeurs de s'éloigner des tests d'intégration et de système pour aller vers le microtesting.

Dan : Je ne pense pas que des recommandations sur les ratios soient utiles. Pour moi, c'est une question de risque. Si la probabilité d'une erreur est élevée ou son impact coûteux, je porterai une plus grande diligence. Par exemple, j'ai tendance à piloter par les tests le code qui transforme les données parce que je sais combien il est facile de casser la transformation, et comment il peut être difficile de détecter l'erreur. De même, lorsque je travaille sur un logiciel à la frontière d'un système qui parle avec le monde extérieur, je suis prudent sur les données que j'envoie et que j'accepte. Si je vois un bug dans une application je vais parfois commencer par écrire un test qui isole le bug, et conduire par les tests le correctif. D'autres fois, je vais exécuter du code dans un REPL (l'interface en ligne de commande d'un langage) et comprendre le bug à partir de là.

Gojko : C'est une question trop générale, je ne peux pas vous donner une réponse sans tenir compte d'un projet en particulier.

Ron : A part « mettez en pratique ces points », non. Il coûte moins cher de développer en utilisant TDD et les pratiques associées, et le résultat est un code meilleur. Il est vrai que certaines personnes et certaines équipes ont l'impression d'avancer trop lentement si elles utilisent TDD. Il peut exister quelques niches de développement pour lesquelles cela est effectivement vrai, mais je n'en ai trouvé aucune. Plus certainement, ils ne sont tout simplement pas encore assez bon en TDD comme probablement pour le reste. Ils pensent alors aller vite, mais ils sont entrain de construire un tas de défauts de plus en plus grand qui devra être pris en charge. Et leur conception se détériore, ce qui augmente encore les défauts, des défauts difficiles à trouver et à corriger, et les progrès ralentissent lorsque les choses se corsent. Ils auront de mauvaises nouvelles quand ils en ont le moins besoin, à savoir dans les dernières semaines de leur projet.

C'est comme ça que vous mettez les équipes à rude épreuve. Les gens et les produits survivent aux épreuves, bien sûr. Le malheur est que après avoir été réunis pour un grand effort et avoir survécu, les équipes en viennent à croire que c'était la seule façon qu'ils pouvaient accomplir tout ce qu'ils ont accompli. C'est tout simplement faux. Ils se sont approchés du suicide quand il y avait un chemin simple qui mène à un meilleur endroit, à portée de main tout le temps.

Steve : Non, sauf si vous avez construit avant un système presque identique avec la même équipe. L'intérêt des techniques agiles est de répondre aux situations qui se présentent. Ces proportions vont changer au cours de la durée de vie du projet.

InfoQ : Systèmes critiques exclus, il semble y avoir aujourd'hui un consensus pour dire qu'une couverture par les test de 100% ne devrait pas être un objectif ou un idéal en soi lors du développement d'un logiciel. Pensez-vous que les efforts portés sur le taux de couverture du code testé peut promouvoir des tests plus ciblés et / ou plus efficaces ?

JB : Au contraire, lorsque des organisations se concentrent sur ces objectifs, ils créent ces maudits « modèles de maturité » que je trouve être un fléau pour notre profession. Vous savez : niveau 1 signifie "nous écrivons des tests", niveau 2 signifie "nous écrivons des tests pour tout nouveau code", niveau 3 signifie "nous avons une couverture de 50% sur l'ensemble du système", et je suppose que le niveau 5 signifie "nous rêvons des tests". Je trouve ça tellement ennuyeux et inutile. Je peux faire toutes ces choses et livrer quand même de très mauvais produits. Je le vois de temps en temps, et on se moque de ce que j'enseigne et pratique.

J'ai commencé à m'occuper de ces choses quand j'ai eu mon "moment Network" – vous savez "Je suis fou de rage, et je commence à en avoir raz le bol" (n.d.t. : « Network » film satyrique de Sidney Lumet dans lequel l'un des personnages exprime sa colère en direct à la télévision). J'essaie de pousser les gens à avoir leurs propres moments Network, puis de leur donner des idées sur la façon de résoudre le problème. Je crois que cela mène beaucoup plus efficacement à des travaux rigoureux que les objectifs de couverture de code.

Dan : Je pense que prescrire un ratio de couverture de tests a exactement l'effet inverse. Il suggère que tout code a la même valeur et est tout aussi risqué, ce qui est manifestement faux. Au lieu de cela je préconise l'application du niveau approprié de diligence et d'examen en fonction du type de code. Le coût d'opportunité pour essayer d'atteindre un seuil de couverture de code testé peut être insensé, par exemple les tests d'interface utilisateur. Ce temps peut être bien mieux investi dans l'amélioration de la qualité du code crucial.

Gojko : Avoir pour objectif un certains taux de couverture de code est ridicule. Une couverture de 10 % des zone à risque peut nous donner un meilleur bénéfice qu'une couverture de 99 % qui ne tient pas compte de ces zones à risque. Je pense que la couverture des risques est un bien meilleur indicateur que la couverture de test. J'aime utiliser la matrice ACC (Attribute Component Capability) pour évaluer les risques et décider ensuite ce qu'il faut couvrir et comment (voir le livre How Google Tests Software by James Whittaker).

Ron : La couverture de test ne doit jamais être un but. Il devrait être évident que, si les tests sont bons, il y aura très peu de défauts sur ce qui a été testé. Où se trouvent les défauts restant ? Là où nous n'avons pas testé. Donc, il n'est pas productif de penser en termes d'une certaine valeur de couverture puisque ce qui est suffisant est d'une certaine manière la perfection. Au lieu de cela, nous devons faire deux choses:

  • Tout d'abord, nous devons continuellement améliorer nos compétences de test, de sorte que de moins en moins des parties du système restent non testées. Il est intéressant de noter que si nous faisons vraiment ce que TDD enseigne: "Ne jamais écrire une ligne de code autre que, en réponse à un test qui a échoué", nous allons automatiquement obtenir une couverture complète, et également une très bonne couverture des chemins d'exécution.

  • Deuxièmement, je recommanderais à l'équipe d'analyser la couverture de test pour qu'elle puisse mieux décider où améliorer les choses. Personne ne peut coder parfaitement, nous devons donc rester vigilants, et quand un défaut se présente, nous devons examiner ce qui s'est passé, écrire les tests manquants, et monter en compétence pour éviter que ce genre de chose ne se reproduise.

Steve : Là encore, c'est préjuger sans parler d'un cas concret, et souvent la distinction des différents cas n'est pas claire. La couverture de code peut être utile pour indiquer les bloques de code à regarder, mais peut fausser les priorités de l'équipe si elle est traitée comme un objectif imposé de l'extérieur.

InfoQ: TDD, BDD, ATDD, Tester d'Abord, Spécification par l'Exemple , etc ... peuvent prendre différentes significations en fonction des personnes et cela peut prêter à confusion. Avons-nous oublié un langage ubiquitaire pour décrire nos méthodologies de développement logiciel et pour développer une
compréhension partagée des bonnes pratiques ?

JB : Non, je ne crois pas. Je pense que nous avons une terminologie suffisamment bonne pour chacune des différentes pratiques. J'ai eu de meilleurs résultats quand j'ai cessé de me soucier de leur définition pour expliquer comment je les comprends, et partager avec les autres ma compréhension. J'ai eu une des discussions les plus cruciales de ma vie en discutant les définitions, la signification et le but de TDD et BDD dans une chambre d'hôtel à 4h30 du matin avec des personnes comme Dan North et Chris Matts. Ce serait dommage d'imposer à la communauté un unique ensemble de définitions et cela découragerait ce genre de vif et ivre débat critique.

Dan : Cela indique que notre compréhension de ce domaine est en pleine évolution. Au départ, j'avais proposé BDD pour aider à enseigner (ma compréhension de) TDD. J'aime la phrase de Gojko Adzic "Spécification par l'Exemple" parce qu'elle est claire et sans ambiguïté. J'ai lutté pendant longtemps avec les mots Test vs. Exemple vs. Spec et je n'ai toujours pas de préférence pour l'un des termes. L'expression "langage ubiquitaire" est elle-même trompeuse. "Ubiquitaire" signifie universel dans un contexte délimité. En d'autres termes nous nous attendons à décrire la même chose différemment selon le contexte. Le Test de quelqu'un est l'Exemple d'un autre, est encore la Spécification d'un autre. Il s'agit de savoir si vous pouvez communiquer clairement votre intention, dans ce contexte.

Gojko : J'ai essayé de définir la Spécification par l'Exemple de manière claire, étroite, et dans un contexte délimité justement pour cette raison, afin d'éviter la confusion totale s'il s'agit de TDD, BDD, ATDD ou autre chose. Je pense que le nom donne beaucoup de sens dans la pratique de l'exploration et pour mettre le doigt sur ce que nous cherchons à construire d'un point de vue métier en utilisant des exemples et en construisant de la documentation vivante. Il y a certaines idées et pratiques qui permettent d'atteindre cet objectif, différentes de celles qui sont utiles quand nous pilotons la conception par les tests techniques, cela a du sens de les considérer comme des pratiques en soi.

Je n'aime pas le nom ATDD ou Acceptance TDD, car il crée une fausse image dans la tête des gens et mène les équipes à l'échec parce qu'elles se concentrent sur les mauvais objectifs. Je voudrais que l'on cesse de l'utiliser, mais il y a malheureusement des livres qui sont sortis récemment qui favorisent ce nom.

La façon dont je comprends BDD, c'est qu'il englobe beaucoup plus que simplement la Spec par l'Exemple et le pilotage de la conception technique avec les tests unitaires. Par exemple, je considère Feature Injection, Requirements Pull, Outside in Design, la définition de modèles pour la valeur métier, etc ... comme faisant partie de BDD. C'est comme cela que Liz Keogh le considère et je trouve cela très excitant. Tout cela est beaucoup plus que les Spec par l'Exemple ou les tests unitaires. Par exemple, Effect Mapping est un nouveau processus de planification passionnant et une nouvelle technique pour établir une feuille de route qui s'inscrit parfaitement dans l'ensemble du système de valeurs de BDD, et rend le pilotage par les tests intéressant au delà de l’objectif métier, et n'a pas de lien avec l'automatisation et n'en a pas besoin.

Ron : Eh bien, je pense que c'est comme cela que les hommes communiquent. Il n'y a pas de mots sans ambiguïté et dont tout le monde partage la même définition. Et dans un métier comme le nôtre, où nous apprenons en chemin, les différences sont inévitables. Les différences les plus importantes, à mon avis, concernent les gens qui ont fait peu ou pas du tout d'effort pour comprendre ce que tout cela signifie. A la place, soit ils dénigrent les idées sans comprendre, soit ils prétendent pratiquer sans vraiment le faire, encore une fois sans comprendre.

Cela a deux graves effets néfastes. Tout d'abord, de nombreux projets, et de nombreuses personnes, ne font pas aussi bien qu'ils le pourraient. Cela conduit à de la souffrance humaine, des échecs de projets, et des résultats inférieurs. La deuxième incompréhension, souvent semblant presque volontaire, ralentit l'intégration de ces bonnes idées.

Steve : Lorsque nous aurons une parfaite connaissance de la discipline, nous pourrons démêler la terminologie :) Je pense que c'est encore trop tôt pour être clair sur ce qui convient. Je pense aussi qu'il devrait y avoir plus de latitude pour différentes «écoles» qui reconnaissent leurs divergences sans vouloir conquérir le monde entier.

InfoQ : Un dernier mot sur ces sujets ?

JB : Rien de nouveau. Pratiquez ces techniques parce que vous espérez qu'elles vous guideront pour améliorer votre travail. Faites-le car cela vous donne une « victoire personnelle ». Faites-le parce que cela vous permet de mieux profiter de votre travail, au diable les autres raisons.

Dan : Tout ce que je viens de dire ici sur ces sujets ne sera probablement pas mes derniers mots !

Ron : Bien que j'utiliserai ces approches sur tout projet, parce que parmi toutes les approches que j'ai utilisées en un demi-siècle ce sont les meilleurs, je ne voudrais pas imposer leur utilisation à tout le monde.

Ce que je vais faire, cependant, est de suggérer que chaque personne qui se soucie de cette profession apprenne ces techniques suffisamment bien pour les appliquer ... disons "vachement bien" ... et seulement alors décider quand et où les appliquer. Cela n'a pas beaucoup de sens de rejeter une technique qui pourrait être utile avant d'en apprendre suffisamment pour l'évaluer en connaissance de cause.

Donc ce que j'ai envie de faire, c'est de montrer ce que je fais dans le développement logiciel, d'apporter un endroit sûr dans lequel pratiquer, en espérant donner l'envie d'aller suffisamment loin pour prendre une décision éclairée.

Pour moi, la bonne décision est d'utiliser ces pratiques de concert, tout le temps. J'espère que les autres partagent mon point de vue.

Steve : Souvent, le principal problème que je rencontre quand on parle à des équipes de TDD ne porte pas sur les tests, mais est lié à la faiblesse des compétences en conception de base; la raison pour laquelle on lutte avec un test est liée à une mauvaise structure du code. De même, je vois du code qui n'est pas assez clairement exprimé. Je pense de plus en plus que lors des entretiens de programmeur on devrait s'assurer que le candidat peut écrire un bloc de code lisible.

A propos des interviewés :

J.B. Rainsberger aide les entreprises logicielles à mieux satisfaire leurs clients et à supporter leur métier (jbrains.ca). Au fil des ans, il a appris à écrire des logiciels de valeur, à améliorer sa communication avec les autres, et il a construit une vie qu'il aime. Il parcourt le monde pour partager ce qu'il a appris, dans l'espoir d'aider les autres à obtenir ce qu'ils veulent de leur travail et de leur vie. Même s'il a beaucoup voyagé en Europe ces deux dernières années, il vit sur la côte est canadienne avec sa femme, Sarah, et trois chats. Vous pouvez retrouver J.B. sur le blog The Whisperer Code.

Dan North développe des logiciels et coache des organisations et des équipes dans l'Agilité et les méthodes Lean. Il donne priorité aux personnes et promeut l'écriture de logiciels simples et pragmatiques. Il croit que la plupart des problèmes auxquels font face les équipes porte sur ​​la communication, c’est pourquoi il attache autant d'importance à trouver les mots justes, et s’enthousiasme pour BDD, la communication et la pédagogie. Il travaille dans l'industrie informatique depuis la fin de ces études en 1991. A l'occasion, il blogue sur dannorth.net.

Gojko Adzic est un consultant expert en stratégie de prestation logicielle qui travaille avec des équipes ambitieuses pour améliorer la qualité de leurs produits et des processus associés. Il est un spécialiste de l'Agilité et du Lean management, en particulier les tests agiles, les spécifications par l'exemple et BDD. Gojko est un conférencier régulier dans les événements majeurs de l'informatique. Il dirige le user group britannique de l'Agile Testing. Au cours des onze dernières années, il a travaillé en tant que développeur, architecte, directeur technique et consultant dans les secteurs de la finance, de l'énergie, des services mobiles, du commerce électronique, des jeux en ligne. Il est l'auteur de plusieurs livres : Specification by Example, Bridging the Communication Gap, Test Driven .NET Development with FitNesse and The Secret Ninja Cucumber Scrolls.

Ron Jeffries est un consultant indépendant dans les méthodes Agile et XP (Xprogramming.com), il a commencé à développer des logiciels avant que la majorité des développeurs soit née. Ron était le coach du projet XP, il est l'auteur de Extreme Programming Adventures in C#, Extreme Programming Installed, et co-créateur des célèbres cours d'Object Mentor's.

Steve Freeman, auteur de "Growing Object Oriented Software, Guided by Tests" (Addison-Wesley), a été un pionnier du développement logiciel Agile au Royaume-Uni. Il a développé des logiciels pour un grand nombre d'institutions, de la petite entreprise aux banques d'investissement multinationales. Steve forme et conseille des équipes de développement à travers le monde. Auparavant, il a travaillé pour des laboratoires de recherche et des éditeurs de logiciels, a obtenu un doctorat (Cambridge), a écrit des applications « sur étagère » pour IBM, et a enseigné à l'University College de Londres. Steve est un présentateur et organisateur de conférences internationales, et a été président de la première XpDay de Londres.

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT