Chapitre 5.3Les tests

Vérifier que le code fonctionne.

3 minutes de lecture

On en a parlé dans le chapitre sur les environnements, les tests automatiques sont au coeur du développement logiciel moderne. Mais concrètement, de quoi parle-t-on ?

Un test automatique, c'est du code qui vérifie que d'autre code fonctionne correctement. Au lieu de cliquer manuellement sur chaque bouton du site pour vérifier que tout marche, les développeurs écrivent des programmes qui font ces vérifications à leur place.

Une fois écrits, ces tests peuvent être relancés des dizaines de fois par jour sans effort, et le sont automatiquement à chaque modification du code par la chaîne d'intégration continue. Ils sont la première ligne de défense contre les bugs et les régressions.

Les différents niveaux de tests

On distingue classiquement trois niveaux, du plus petit au plus large, chacun vérifiant une chose différente.

Les tests unitaires

Ils testent une seule petite brique du code, de manière isolée.

Prenons une fonction qui calcule un prix TTC. Mon test unitaire vérifie que calculerPrixTTC(100, 20) retourne bien 120, et que calculerPrixTTC(0, 20) retourne 0. C'est rapide, ciblé, et si ça casse, on sait immédiatement où est le problème.

Les tests unitaires sont les plus nombreux dans un projet. Un bon projet peut en avoir des centaines, voire des milliers. Ils s'exécutent en quelques secondes.

Les tests fonctionnels (ou d'intégration)

Ils ne testent plus une brique isolée mais plusieurs qui travaillent ensemble.

Cette fois, je simule un utilisateur qui se connecte, ajoute un produit au panier, entre ses coordonnées bancaires et valide le paiement. Le test vérifie que la commande est bien créée, que le stock est mis à jour et que l'email de confirmation est envoyé.

Ces tests sont plus lents car ils sollicitent une bonne partie du système, mais ils vérifient que les pièces du puzzle s'assemblent correctement.

Les tests de bout en bout

Dernier niveau, le plus proche du réel. Un robot pilote un vrai navigateur sur une vraie version du site, clique sur les boutons et remplit les formulaires comme le ferait un client.

On dit aussi "end-to-end", souvent abrégé E2E. Ce sont les tests les plus convaincants, puisqu'ils vérifient exactement ce que l'utilisateur vivra. Ce sont aussi les plus lents, les plus coûteux à maintenir, et ceux qui échouent le plus souvent pour de mauvaises raisons, un bouton déplacé ou une page un peu longue à charger.

Le BDD : décrire le comportement attendu

Le Behavior Driven Development (BDD) est une approche qui rapproche les développeurs des équipes métier. Les critères de validation d'une fonctionnalité y sont écrits dans un langage compréhensible par tout le monde, pas seulement par les développeurs.

Ce langage s'appelle Gherkin, et l'outil qui l'a rendu populaire s'appelle Cucumber. La structure est volontairement simple :

Un scénario Gherkin
Étant donné un client avec un abonnement premium
Quand il ajoute un produit à 50€ au panier
Alors une réduction de 10% est appliquée
Et le total affiché est de 45€

Ce scénario est écrit en collaboration avec le demandeur (chef de produit, product owner...). Le développeur le transforme ensuite en test automatique. Si le test passe, la fonctionnalité est validée.

L'intérêt du BDD, c'est que les critères de validation sont clairs pour tout le monde avant le début du développement. Ça évite les malentendus et les allers-retours.

Le TDD : tester d'abord, coder ensuite

Le Test Driven Development (TDD) pousse la logique encore plus loin, puisqu'on écrit le test avant le code.

Le cycle est simple :

  1. Rouge : écrire un test qui échoue (le code n'existe pas encore).
  2. Vert : écrire le minimum de code pour faire passer le test.
  3. Refactoring : améliorer le code tout en s'assurant que le test passe toujours.

Ce cycle se répète en boucle, test par test, fonctionnalité par fonctionnalité.

Le TDD est un sujet qui divise la communauté. Ses partisans affirment qu'il produit un code mieux conçu, plus testable et plus fiable. Ses détracteurs trouvent que c'est trop rigide et que ça ralentit le développement.

De mon expérience, la vérité est entre les deux. Le TDD est un excellent exercice pour les développeurs en formation. Il force à réfléchir au "quoi" avant le "comment". En pratique, les développeurs expérimentés alternent entre TDD et approche classique selon la complexité du sujet.

La pyramide des tests

Ces trois niveaux ne se valent pas en quantité. L'image qui circule depuis une quinzaine d'années, popularisée par Mike Cohn, est celle d'une pyramide :

  • Base (large) : beaucoup de tests unitaires, rapides et ciblés.
  • Milieu : moins de tests d'intégration, qui vérifient les assemblages.
  • Sommet (étroit) : très peu de tests de bout en bout, qui rejouent les quelques parcours vraiment critiques, typiquement l'inscription et le paiement.

L'erreur classique consiste à inverser la pyramide, en n'ayant que des tests de bout en bout. Ils sont lents, fragiles et quand ils échouent, on ne sait pas d'où vient le problème.

Un projet sans tests, c'est un avion sans instruments de bord. Ça vole, mais personne n'ose toucher à quoi que ce soit de peur que tout s'effondre. Les mises en production deviennent stressantes, et les bugs sont découverts par les utilisateurs au lieu des développeurs.

PrécédentLa programmation objet Tous les chapitres