Les 3 clés pour maîtriser le Test Driven Development : TDD

Dans le domaine du test logiciel, l’acronyme TDD signifie Test Driven Development. En français, ce terme peut être traduit par : le développement piloté par les tests. C’est une méthodologie de développement logiciel pilotée par les tests, dans laquelle les développeurs corrigent les bugs au fur et à mesure de la programmation. Cette technique est mise en place dans des équipes agile. Maîtriser le Test Driven Development : TDD est important car cela permet de gagner du temps, d’améliorer la testabilité et la maintenabilité des fonctionnalités du code.

Dans cet article, nous allons vous présenter 3 clés pour maîtriser le Test Driven Development mises en lumière par des experts depuis la création de cette technique.

Voici les 3 clés pour maitriser le développement piloté par les tests :

  1. Avoir une compréhension exhaustive de ce que représente le Test Driven Development : TDD
  2. Faire en sorte que le code non testable devienne testable
  3. Acquérir de l’expérience en pratiquant le Test Driven Development : TDD

1. Avoir une compréhension exhaustive de ce que représente le Test Driven Development : TDD

Le premier ingrédient clé pour être efficace avec le développement piloté par les tests est de comprendre ce qu’il représente vraiment. Il y a beaucoup d’idées fausses sur la façon d’appliquer correctement le Test-Driven Development. Dans le cadre de l’application de cette technique, les erreurs se paient cher, donc il faut être très méthodique.

All4Test 3 clés pour maîtriser le Test Driven Development (TDD)

Il nous est malheureusement impossible de résumer la méthode TDD dans ce bref article. Mais il y a un événement sur lequel il est impossible de faire l’impasse.

Parfois, le développement piloté par les tests est confondu à tort avec une forme de test ou d’assurance qualité. Or, ça n’est pas le cas.

Il y a un état d’esprit particulier dans lequel il faut se mettre lorsqu’on pratique le TDD. L’état d’esprit du service QA consiste à penser à ce qui pourrait mal tourner et à trouver des moyens de s’assurer que cela ne se produise pas. L’état d’esprit du développeur est cependant plus optimiste : il se concentre sur ce qui doit se passer pour que les choses se déroulent correctement.

Plutôt que de penser à faire du TDD comme une façon de tester du code, nous devons penser à faire du TDD comme une façon de déterminer et préciser des comportements donnés dans le processus global.

Cela nous amène à créer des types de tests très différents qui ont tendance à être plus résistants aux changements futurs. De ce fait, on cherche à vérifier des comportements plutôt que de tester des morceaux de code indépendamment les uns des autres.

Le terme « test unitaire » peut également être quelque peu trompeur. Le terme « test unitaire » peut également prêter à confusion. Si le test est écrit avant même d’écrire le code, alors ce n’est pas vraiment un test. En effet, au moment où ce test est rédigé, il n’y a encore rien à tester. À ce stade, il est un peu étrange d’appeler cela un test : il serait plus pertinent d’appeler ça “une hypothèse”.En effet, lorsque nous écrivons le test avant d’écrire le code, nous émettons des hypothèses sur la façon dont le code se comportera, sur ce que nous devons lui transmettre et sur ce qu’il renverra comme informations.

Cela ressemble à la façon dont nous abordons la science. Nous ne faisons pas d’expériences au hasard. Nous commençons toujours par une hypothèse : quelque chose que nous essayons de prouver ou de réfuter. Nous pouvons ensuite concevoir une expérience pour prouver ou réfuter notre hypothèse.

Mais il existe une confusion encore plus répandue, à laquelle les gens s’accrochent vraiment lorsqu’ils essaient de faire du TDD. Il s’agit de leur définition d’une “unité”. Lorsqu’ils voient le mot « unité » dans le terme « test unitaire », la plupart des développeurs pensent à une unité de code, comme une méthode ou un bloc d’instructions, ou même une seule ligne de code. Or, dans ce contexte, ce n’est pas la définition adéquate. Le terme « unité » a surtout été adopté pour mettre l’accent sur une unité de comportement fonctionnellement indépendante.

Idéalement, le comportement que nous recherchons est en relation directe avec les critères d’acceptation que nous essayons d’atteindre. Lorsque les tests unitaires sont également des tests d’acceptation, nous obtenons sans contrepartie la traçabilité et la vérifiabilité des exigences.

Une « unité de comportement » peut impliquer plusieurs éléments fonctionnant en coordination. Par exemple, pour tester les règles relatives à la participation à une enchère, il faut qu’un élément “vendeur” crée un élément “enchère” et qu’un élément “enchérisseur” participe à cette enchère. Certains appelleraient cela un test d’intégration car il implique l’interaction de plusieurs éléments. Or, cela correspond plutôt à un test unitaire car seule une unité de comportement est testée : l’enchère.

Souvent, lorsque nous nous concentrons sur la création de fonctionnalités qui répondent aux critères d’acceptation, nous écrivons du code dont la maintenance est nettement moins coûteuse, car la conception est plus simple à comprendre et à étendre.

2. Faire en sorte que le code non testable devienne testable

Le deuxième élément clé de l’apprentissage du TDD consiste à maîtriser toute une série de techniques qui rendent le code non testable testable. Une grande partie du code existant est très difficile à tester. Lorsqu’il faut interagir avec ce code, il peut être difficile de le tester.

3 clés pour maîtriser le Test Driven Development (TDD)

L’un des plus grands problèmes présent dans le code des nombreuses entreprises est que pour utiliser un même service, un client doit lancer une requête et appeler directement ce service. De l’extérieur, le service et le client du service semblent être la même chose et ne peuvent être séparés. Mais lorsque cette opération est répétée à l’infini dans un système, celui-ci devient un véritable enchevêtrement de code qu’il est impossible de séparer et de tester indépendamment.

Une solution à ce problème est une technique appelée injection de dépendances. Vous connaissez peut-être les frameworks d’injection de dépendances, comme Spring. Mais vous pouvez injecter des dépendances manuellement, sans utiliser de framework. Au lieu de faire en sorte qu’un objet instancie un service pour ensuite l’utiliser, nous déléguons l’instanciation à un objet différent, puis nous passons la référence au client qui l’utilise.

Permettre à la référence à un service d’être passée au consommateur du service nous permet de passer dans un faux lorsque nous testons. Il s’agit d’un concept simple qui est d’une importance vitale pour créer de petites unités de comportement testables et briser le code monolithique.

Il existe plusieurs types de fakes pour remplacer une dépendance. Une approche consiste à créer un mock artisanal en sous-classant simplement la dépendance et en surchargeant les méthodes avec lesquelles votre code interagit. Au lieu d’appeler la vraie dépendance, vous pouvez appeler la méthode surchargée de votre mock, qui peut renvoyer tout ce qui a du sens. Rappelez-vous, l’objectif ici est de tester l’interaction de notre code avec la dépendance externe, et non la dépendance elle-même.

3. Acquérir de l’expérience en pratiquant le Test Driven Development : TDD

Avoir les compétences pour écrire de bons tests de comportements et être capable d’écrire un bon code testable n’est qu’une partie de ce qui est nécessaire pour maîtriser le TDD. Le troisième est l’élément le plus important pour maîtriser le développement piloté par les tests est d’en faire l’expérience. Lorsque les développeurs ont pratiqué le développement piloté par les tests et qu’ils constatent que leurs tests détectent immédiatement les problèmes – et que leur code s’en trouve amélioré – ils commencent à s’intéresser à la méthode TDD dans leurs projets.

Il est utile d’apprendre le développement piloté par les tests dans le cadre d’un nouveau projet, car il y a beaucoup plus de complications à faire du développement piloté par les tests sur du code hérité. Il s’agit en soi d’un domaine d’étude à part entière, et quelques excellents livres ont été publiés sur le sujet. Tout développeur de logiciels professionnel devrait lire Refactoring de Martin Fowler : Improving the Design of Existing Code. Et si vous travaillez sur du code hérité, vous devriez également lire Working Effectively with Legacy Code de Michael C. Feathers – et n’oubliez pas de consulter le livre, Beyond Legacy Code : Nine Practices to Extend the Life (and Value) of Your Software.

C’est par la pratique que l’on constate par soi-même les avantages du TDD. C’est vraiment la seule façon d’apprendre et d’acquérir de nouveaux comportements : en les pratiquant et en se prouvant à soi-même qu’ils ont de la valeur. On ne peut pas faire cette expérience en écoutant quelqu’un d’autre parler d’un sujet.

Comprendre ce qu’est réellement la TDD, savoir comment rendre du code non testable testable et acquérir de la pratique en expérimentant les avantages de la TDD sur un projet sont les trois ingrédients clés pour maîtriser la TDD. Le constat est clair : lorsque les développeurs disposent de ces trois ingrédients, ils s’enthousiasment pour la TDD et continuent à l’appliquer dans leurs projets.

Si vous voulez aller plus loin sur le TDD : Test-Driven Development, vous pouvez consuler notre présentation vidéo du TDD par l’exemple.

Le TDD est souvent inclus dans une approche Clean Code, Craftsmanships pour laqelle nous proposons une formation et du coaching : https://www.all4test.fr/formations/en-ligne/clean-code-coder-proprement/

Nous vous remercions pour votre lecture.

Source : Agileconnection.com

Si vous voulez mettre en place le développement piloté par les tests TDD dans votre équipe, projet ou entreprise, All4Test est expérimenté sur le sujet.
N’hésitez pas à nous contacter si vous voulez en savoir plus !