Qu’est-ce que le développement piloté par les Tests (TDD) ?

large__8282043567 Le développement piloté par les tests est un processus qui repose sur la répétition d’un cycle de développement très court. Il est basé sur le concept de programmation extrême (XP) qui encourage la conception simple avec un haut niveau de confiance.

La procédure de TDD est la suivante:

  1. Ecrire un test
  2. Exécuter tous les tests
  3. Écrire le code d’implémentation
  4. Exécuter tous les tests
  5. Refactor

Cette procédure est souvent appelée Red-Green-Refactor.

Lors de l’écriture des tests, nous sommes à l’état rouge. Puisque le test est écrit avant l’implémentation réelle, il est censé échouer. Si ce n’est pas le cas, le test est faux. Il décrit quelque chose qui existe déjà ou qui a été mal écrit. Être en vert lors de la rédaction des tests est un signe de faux positif. Des tests comme celui-ci devraient être supprimés ou refactorisés.

Vient ensuite l’état vert. Lorsque la mise en œuvre du dernier test est terminée, tous les tests doivent réussir. Si ce n’est pas le cas, la mise en œuvre est erronée et doit être corrigée.

L’idée n’est pas de rendre l’implémentation finale, mais de fournir juste assez de code pour que les tests passent. Une fois que tout est vert, nous pouvons procéder à la refactorisation du code existant. Cela signifie que nous rendons le code plus optimal sans introduire de nouvelles fonctionnalités. Pendant que le refactoring est en place, tous les tests doivent passer tout le temps. Si l’un d’eux échoue, refactor a cassé une fonctionnalité existante. Le refactoring ne devrait pas inclure de nouveaux tests.

La vitesse est la clé

large_5836417589
J’ai tendance à voir le TDD comme un jeu de ping-pong (ou de tennis de table). Le jeu est très rapide. Il en va de même pour TDD. J’ai tendance à ne pas passer plus d’une minute de chaque côté de la table (test et implémentation). Écrivez un test court et exécutez-le (ping), écrivez l’implémentation et exécutez tous les tests (pong), écrivez un autre test (ping), écrivez l’implémentation de ce test (pong), refactorisez et confirmez que tous les tests sont réussis (score), répétez. Ping-pong, ping-pong, ping-pong, ping-pong, marquer, servir à nouveau. N’essayez pas de faire le code parfait. Au lieu de cela, essayez de garder le ballon jusqu’à ce que vous pensiez que le moment est venu de marquer (refactor).

Il ne s’agit pas de tester

T dans TDD est souvent mal compris. TDD est la façon dont nous abordons la conception. C’est le moyen de nous forcer à réfléchir à l’implémentation avant d’écrire le code. C’est le moyen de mieux structurer le code. Cela ne signifie pas que les tests résultant de l’utilisation de TDD sont inutiles. Loin de là. Ils sont très utiles et nous permettent de nous développer à grande vitesse sans avoir peur que quelque chose soit cassé. Cela est particulièrement vrai lorsque le refactoring a lieu. Pouvoir réorganiser le code tout en ayant la certitude qu’aucune fonctionnalité n’est cassée est un énorme coup de pouce à la qualité du code.

L’objectif principal de TDD est la conception de code avec des tests comme produit secondaire très utile.

Moquerie

Pour que les tests s’exécutent rapidement et fournissent un retour constant, le code doit être organisé de manière à ce que les méthodes, les fonctions et les classes puissent être facilement moquées et écrasées. La vitesse d’exécution en sera gravement affectée, par exemple, nos tests doivent communiquer avec la base de données. En se moquant des dépendances externes, nous sommes en mesure d’augmenter considérablement cette vitesse. L’exécution de la suite de tests unitaires entiers doit être mesurée en minutes sinon en secondes. Plus important encore que la vitesse, la conception du code de manière à ce qu’il puisse être facilement moqué et tronqué nous oblige à mieux structurer ce code en appliquant une séparation des préoccupations. Avec ou sans railleries, le code doit être écrit de manière à pouvoir, par exemple, facilement remplacer une base de données par une autre. Cet « autre » peut être, par exemple, moqué ou une base de données en mémoire.

Un exemple de moquerie dans Scala peut être trouvé dans l’article Scala Test-Driven Development (TDD): Opérations de fichiers de test unitaires avec Specs2 et Mockito. Si votre langage de programmation de choix n’est pas Scala, article peut toujours être très utile afin de voir le modèle qui peut être appliqué à n’importe quel langage.

Watchers

Les watchers sont des outils très utiles lorsque vous travaillez à la mode TDD. Ce sont des frameworks ou des outils qui sont exécutés avant de commencer à travailler et qui surveillent tout changement dans le code. Lorsqu’un tel changement est détecté, tous les tests sont exécutés. Dans le cas de JavaScript, presque tous les systèmes de construction et les coureurs de tâches le permettent. Gulp (mon préféré) et Grunt sont deux exemples parmi tant d’autres. Scala a sbt-revolver (entre autres). La plupart des autres langages de programmation ont des outils similaires qui recompilent (si nécessaire) et exécutent tous les tests (ou affectés) lorsque le code change. Je finis toujours par avoir mon écran divisé en deux fenêtres. L’un avec le code sur lequel je travaille et l’autre avec les résultats de tests qui sont exécutés continuellement. Tout ce que j’ai à faire est de faire attention à ce que la sortie de ces observateurs corresponde à la phase dans laquelle je suis (rouge ou verte).

Documentation

Un autre effet secondaire très utile du TDD (et des tests bien structurés en général) est la documentation. Dans la plupart des cas, il est beaucoup plus facile de savoir ce que fait le code en regardant les tests que l’implémentation elle-même. Un avantage supplémentaire que d’autres types de documentation ne peuvent pas fournir est que les tests ne sont jamais obsolètes. En cas de divergence entre les tests et le code d’implémentation, les tests échouent. L’échec des tests signifie une documentation inexacte.

L’article Tests as documentation fournit un raisonnement un peu plus approfondi derrière l’utilisation de tests au lieu de la documentation traditionnelle.

Résumé

D’après mon expérience, TDD est probablement l’outil le plus important que nous ayons dans notre boîte à outils logicielle. Il faut beaucoup de temps et de patience pour maîtriser le TDD, mais une fois cet art maîtrisé, la productivité et la qualité augmentent considérablement. La meilleure façon d’apprendre et de pratiquer le TDD est en combinaison avec la programmation par paires. Comme dans un jeu de ping-pong qui nécessite deux participants, TDD peut être par paires où un codeur écrit des tests et l’autre écrit la mise en œuvre de ces tests. Les rôles peuvent changer après chaque test (comme c’est souvent le cas dans les dojos de codage).

Essayez-le et n’abandonnez pas face aux obstacles car ils seront nombreux.

Développement piloté par les tests (TDD): Les meilleures pratiques Utilisant des exemples Java sont un bon point de départ. Même s’il utilise des exemples Java, les mêmes pratiques, sinon toutes, peuvent être appliquées à n’importe quel langage de programmation. Pour un exemple en Java (comme dans le cas précédent, il est facilement applicable à d’autres langues), veuillez consulter l’exemple d’article de procédure pas à pas de TDD.

Un autre excellent moyen de perfectionner les compétences TDD sont les katas de code (il y en a beaucoup sur ce site).

Quelle est votre expérience avec TDD? Il y a autant de variantes qu’il y a d’équipes qui la pratiquent et j’aimerais entendre parler de votre expérience.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.