Simyl
simylflow
Accueil du cours
Module 2 : Pratiques techniques
Leçon 1 sur 5
14 min

Développement piloté par les tests

Écrivez d'abord le test, laissez-le guider la conception et renforcez votre confiance à chaque frappe.

1Le cycle rouge-vert-refactoring

Le développement piloté par les tests est simple à décrire et difficile à maîtriser :

  1. Rouge : Écrivez un test qui échoue pour la prochaine petite fonctionnalité
  2. Vert : Écrivez le code minimum pour faire passer le test
  3. Refactoring : Nettoyez le code tout en gardant les tests verts

C'est tout. Trois étapes, répétées des centaines de fois par jour.

L'ordre est important. Vous écrivez le test d'abord, avant qu'aucun code de production n'existe. Cela semble à l'envers au début. Mais ça change tout :

  • Vous réfléchissez à comment le code sera utilisé avant de penser à comment il sera implémenté
  • Vous obtenez une rétroaction immédiate sur le fonctionnement de votre code
  • Vous construisez un filet de sécurité qui permet des changements sans crainte
  • Vous créez une documentation exécutable de ce que fait le code

Le TDD est de la conception

Le TDD est une technique de conception déguisée en technique de test. Les tests ne sont pas le but — c'est la réflexion qui les produit qui l'est.

2Écrire le test en premier

La partie la plus difficile du TDD est d'apprendre à écrire des tests pour du code qui n'existe pas encore. Voici comment :

Commencez par l'interface, pas l'implémentation. À quoi devrait ressembler le code une fois terminé ? Écrivez un test qui l'utilise de cette façon.

Commencez petit. N'essayez pas de tout tester en même temps. Testez d'abord le cas le plus simple possible.

Faites-le échouer pour la bonne raison. Le test devrait échouer parce que la fonctionnalité n'existe pas, pas parce que vous avez fait une erreur de syntaxe.

Utilisez les noms de tests comme documentation. Le nom du test devrait décrire le comportement que vous testez : « retourne une liste vide quand aucun élément ne correspond au filtre » et non « test1 ».

Écrire le test en premier vous force à réfléchir à :

  • Quelles entrées ce code nécessite-t-il ?
  • Quelles sorties devrait-il produire ?
  • Que se passe-t-il dans les cas limites ?
  • Comment les autres codes appelleront-ils ceci ?

Ce sont des questions de conception. En y répondant avant d'écrire le code, vous prenez de meilleures décisions de conception.

Bonne approche test d'abord

Besoin d'une fonction pour calculer les frais de livraison. Écrivez un test : « livraison en Californie avec une commande de 50 $ coûte 5 $ ». Ensuite, écrivez juste assez de code pour le faire passer. Puis testez le cas suivant.

Piège du test après

Écrivez tout le calcul de livraison avec tous les cas limites. Ensuite, essayez d'écrire des tests. Découvrez que le code est difficile à tester parce qu'il n'a pas été conçu pour la testabilité. Écrivez des tests désordonnés ou sautez les tests.

3Le faire passer (de la bonne façon)

Une fois que vous avez un test qui échoue, faites-le passer. Mais voici la discipline : écrivez le code minimum pour faire passer le test, pas plus.

Cela signifie :

  • Si une constante fait passer le test, utilisez une constante
  • Si coder en dur une valeur de retour fonctionne, codez-la en dur
  • Ne généralisez pas tant que vous n'avez pas de tests qui nécessitent une généralisation

Cela semble ridicule. « Juste retourner 5 ? » Oui, si cela fait passer le test. Ensuite, écrivez un autre test qui vous force à faire un vrai calcul.

Pourquoi ? Parce que :

  • Vous construisez la fonctionnalité par petites étapes vérifiées
  • Vous n'écrivez jamais de code dont vous n'avez pas besoin
  • Vous découvrez la conception de manière incrémentale
  • Chaque ligne de code est justifiée par un test

La magie se produit quand vous triangulez. Premier test : retournez 5. Deuxième test (entrée différente) : maintenant vous devez calculer. Troisième test : maintenant vous devez gérer les cas limites. Chaque test vous pousse vers une vraie implémentation.

Si vous pouvez faire passer le test en écrivant « return 5 », écrivez « return 5 ». Ensuite, écrivez un autre test qui le casse. Laissez les tests vous guider vers du vrai code.

4L'étape de refactoring

Après que le test passe, nettoyez. Ce n'est pas optionnel.

L'étape de refactoring est où vous :

  • Éliminez la duplication (DRY : Don't Repeat Yourself)
  • Améliorez les noms (faites en sorte que le code se lise comme de la prose)
  • Simplifiez la logique (réduisez la charge cognitive)
  • Réorganisez (déplacez le code là où il appartient)

La clé : gardez les tests verts tout au long. Refactorisez par petites étapes, en exécutant les tests après chaque changement. Si les tests échouent, vous savez exactement ce qui s'est cassé.

C'est là que le TDD porte ses fruits. Sans tests, le refactoring est terrifiant — vous pourriez casser quelque chose. Avec les tests, le refactoring est routinier — vous saurez immédiatement si vous cassez quelque chose.

Sauter l'étape de refactoring mène à ce que Kent Beck appelle des « excuses vertes rapides ». Le code fonctionne, mais il est désordonné. Le désordre s'accumule. Bientôt, la base de code est difficile à utiliser, et vous avez perdu le bénéfice du TDD.

5Mythes du TDD démystifiés

Mythe : Le TDD est plus lent. Réalité : Le TDD semble plus lent au début parce que vous écrivez plus de code. Mais vous passez moins de temps à déboguer, moins de temps dans le débogueur, moins de temps à corriger les bogues en production. Sur la durée de vie de la base de code, le TDD est plus rapide.

Mythe : Le TDD mène à des tests excessifs. Réalité : Le TDD mène exactement aux tests dont vous avez besoin — ni plus, ni moins. Vous testez ce que vous construisez. Tester après mène souvent à des tests manquants (vous oubliez les cas limites) ou à des tests redondants (vous testez la même chose de plusieurs façons).

Mythe : Le TDD ne fonctionne pas pour [mon domaine]. Réalité : Le TDD fonctionne pour tout code qui peut être testé. Si votre code ne peut pas être testé, c'est un problème de conception. Le TDD vous force à écrire du code testable, qui est un meilleur code.

Mythe : Nous n'avons pas le temps pour le TDD. Réalité : Vous n'avez pas le temps de ne pas le faire. Les bogues coûtent cher. Le débogage coûte cher. Les incidents en production coûtent cher. Le TDD est un investissement qui rapporte.

Non négociable

Dans XP, le TDD n'est pas un plus. C'est une pratique non négociable. Sans tests, toutes les autres pratiques deviennent plus difficiles ou impossibles.

Points clés
  • Le TDD suit le cycle rouge-vert-refactoring : échouer, passer, nettoyer
  • Écrivez le test en premier — c'est une technique de conception, pas seulement de test
  • Faites passer les tests avec le code minimum nécessaire, puis itérez
  • Ne sautez jamais l'étape de refactoring — c'est là que la qualité se construit
  • Le TDD est plus rapide à long terme malgré qu'il semble plus lent au début
Pièges courants à éviter
  • Écrire les tests après le code (vous perdez le bénéfice de conception)
  • Sauter l'étape de refactoring (la qualité du code se dégrade)
  • Tester les détails d'implémentation au lieu du comportement
  • Écrire trop de code avant le prochain test

Exercices pratiques