La Duck Conf 2025 - CR : "Tests pragmatiques : comment (presque) arrêter les tests automatisés ?"

Lors de la Duck Conf 2025, Antoine Mazure, Tech Lead et expert Backend, nous a partagé ses propositions pour (presque) arrêter les tests automatisés. Issu de la théorie et de ses retours d’expériences, je vous partage ses enseignements afin de vous aider à optimiser vos pratiques de test sans compromettre la qualité.

Antoine Mazure, Tech Lead et expert Backend, nous a partagé ses propositions pour (presque) arrêter les tests automatisés

Un peu de contexte : le Chaostrateur

Antoine débute en nous décrivant le contexte de son retour d’expérience : il a travaillé au sein d’une équipe de 7 développeurs, sur une base de code existante récupérée sans passation. Cette base de code est composée d’un tunnel de vente qui s’appuie sur une API, qui orchestre les interconnexions avec des progiciels partenaires.

Le Chaostrateur propose un tunnel de vente côté front, ainsi qu’une API qui s’appuie sur de nombreux progiciels partenaires

À l’occasion d’une nouvelle fonctionnalité estimée par l’équipe comme simple à développer, ils se sont aperçus que le code était comme verrouillé par les tests. Pire, ils les ralentissaient et coutaient cher à maintenir, sans leur apporter la confiance qu’ils sont censés apporter.

Une première analyse leur a montré qu’il y avait 9 lignes de tests pour 1 ligne de code de production.

Après analyse, l’équipe s’est rendue compte qu’il y avait 9 fois plus de lignes de tests que de lignes de code

Cet événement a fait réfléchir l’équipe sur la stratégie de tests à mettre en place. Elle a profité de l’introduction d’un nouveau progiciel partenaire pour tester de nouvelles pratiques dont je vais vous partager les enseignements.

Mais avant d’aller plus loin, pourquoi tester ?

Antoine nous rappelle qu’il est important de tester le code de production pour :

  1. S’assurer que le code fonctionne
  2. Mettre en place un filet de sécurité et éviter les régressions
  3. Sécuriser les refactorings
  4. Documenter les fonctionnalités

Les tests n’étant pas déployés en production, on peut se permettre de les remanier ou de les supprimer sans risque pour le code. C’est un entretien nécessaire, car dixit Antoine : “La qualité, il la faut également dans les tests” .

Enseignement 1 : Challengez la stratégie de test en permanence

Une stratégie de test est indispensable afin d’orienter la manière dont une application est testée. Elle définit :

  1. Comment tester l’application : quels types de tests sont nécessaires ? Tests end-to-end ? Tests unitaires ? Tests manuels ? Ce point fait directement écho à la pyramide de tests, initialement décrite par Mike Cohn dans le livre Succeeding with Agile.
  2. Ce qu’il faut ou ne faut pas tester
  3. Les outils de tests à utiliser
  4. Les pratiques de tests (qui s’en occupe, quand, dans quel format…)

Antoine l’affirme : “il n’existe pas de stratégie de test universelle”. Se former et pratiquer est donc indispensable afin d’améliorer la maîtrise des pratiques, pour aboutir à une stratégie de test pragmatique et non dogmatique. Comme développé par Mark Seemann dans son article What to test and not to test, Antoine considère le dogmatisme comme un préalable au pragmatisme : commencer par apprendre et mettre en pratique, pour ensuite challenger les règles en tenant compte du contexte de mise en pratique.

Le dogmatisme diminue quand le niveau d’expertise permet de questionner les règles

Enseignement 2 : Testez les fonctionnalités, et non l'implémentation

Pour ce deuxième enseignement, Antoine reprend le contexte de son retour d’expérience sur le Chaostrateur : lorsque son équipe a voulu refactorer une fonctionnalité, elle a été confrontée à du code couvert par de nombreux tests qui verrouillaient les évolutions de ce code.

Au moindre changement d’implémentation, des tests passaient au rouge alors que la fonctionnalité était fondamentalement fonctionnelle.

Le moindre changement sur le code faisait passer les tests au rouge, alors que la logique fonctionnelle était toujours valide

L’équipe a donc fait le choix de mettre un premier type de test en place : des tests d’orchestration. L’objectif de ces tests est de s’assurer que la logique fonctionnelle est valide, de se concentrer sur la finalité de la fonctionnalité et non sur la manière dont elle est implémentée.

Antoine s’appuie sur l’exemple suivant :

  • Fonctionnalité : Le paiement d’un panier entraîne la création d’une facture
  • Comportements vérifiés au travers du test d’orchestration :
    • L’authentification est bien effectuée
    • Le paiement se fait au bon prix
    • La facture est bien créée

Une fois le test posé, l’équipe a pu refactorer le code en s’assurant que la logique fonctionnelle était toujours valide.

Orienter les tests sur le comportement de la fonctionnalité a permis de refactorer le code en toute sécurité

Enseignement 3 : Arrêtez de tester TOUT votre code

Cet enseignement peut paraître contre-intuitif, d’autant plus dans des contextes où on pousse à une couverture de code très élevée, et pourtant, Antoine nous incite à nous concentrer sur les tests qui couvrent :

  • des fonctionnalités complexes : il peut s’agir d’un algorithme compliqué, de LA fonctionnalité clé du logiciel, de règles métiers riches…
  • des fonctionnalités sensibles : ici, on pense par exemple à l’authentification, à la sécurité, au paiement…

Au détriment du code qui n’est ni complexe, ni sensible (exemple : getters, fonctionnalités de mapping ou de passe-plat…).

Reprenant les principes de la matrice d’Eisenhower, Antoine nous propose une matrice favorisant les tests complexes et sensibles

Reprenant les principes de la matrice d’Eisenhower, Antoine nous propose une matrice favorisant les tests complexes et sensibles. En complément de cette matrice, Antoine nous propose également de poser des tests :

  • en cas de doutes sur un fonctionnement, afin de le clarifier
  • en cas de bugs identifiés, afin de s’assurer qu’ils ne se reproduiront pas

Enseignement 4 : Supprimez vos tests sans culpabiliser

Le Chaostrateur disposait de 600 tests end-to-end dont une partie, nous l’avons vu précédemment, était redondante. Le temps d’exécution était de 15 minutes, rendant la boucle de feedback très longue dans un contexte où l’équipe pratique le Test Driven Development (TDD).

Antoine préconise d’oser supprimer des tests : cela fait partie de l’entretien de la base de code et de son refactoring. Il est d’autant plus aisé de les supprimer que :

  • les tests sont inutiles en production, ils n’affectent pas le code en lui-même
  • les tests sont théoriquement découplés entre eux : si ce n’est pas le cas, vous avez un autre axe de refactoring des tests

La suppression de tests redondants permet de réduire la boucle de feedback et de faciliter le refactoring ou l’évolution de la base de code.

La réduction de la boucle de feedback facilite l’évolution de la base de code

En effet, le fait que les tests s’exécutent plus rapidement permet aux développeurs d’avoir un retour rapide sur la qualité du code qu’ils sont en train de modifier. Ils peuvent rapidement savoir si les règles métiers sont toujours fonctionnelles et rectifier, au besoin, ce qu’ils sont en train de faire. C’est un réel gain en termes d’efficacité.

Enseignement 5 : Testez en priorité ce que vos utilisateurs utilisent

Pour ce dernier enseignement, Antoine reprend et réadapte la loi de Pareto dans le contexte du Chaostrateur : il nous propose de mettre en place un test end-to-end par progiciel, qui couvre 80% des cas d’usages.

Cela permet de réduire le nombre de tests end-to-end, accélérant de fait la boucle de feedback.

Un test end-to-end pour couvrir 80% des cas afin de réduire la boucle de feedback

Il nous propose également que l’exécution des tests end-to-end dépende de l’environnement de recette afin de détecter au plus tôt les changements de contrat d’interface avec les progiciels. Cela peut paraître contre-intuitif, mais c’est la solution que l’équipe a identifiée pour réduire cette boucle de feedback : avant sa mise en place, ils détectaient les changements de contrat d’interface de leurs partenaires directement en production.

Bilan

Dans le contexte du Chaostrateur, l’équipe a redéfini sa stratégie de test pour arriver à :

  • 1 test end-to-end qui parcourt les fonctionnalités les plus utilisées ;
  • 78 tests d’orchestration (un par scénario métier) ;
  • 121 tests de complexité, effectués sur du code sensible ou complexe.

Pour appuyer le bilan, Antoine compare la situation actuelle à la situation initiale :

Avant

Après

9 lignes de tests pour 1 ligne de code

1,2 lignes de tests pour 1 ligne de code (soit 86% de lignes de tests par ligne de code)

Code coverage de 86%

Code coverage de 85%

Exécution des tests en 12mn

Exécution des tests en 10 secondes (soit une réduction de la boucle de feedback de 98%)

Take away : passez aux tests pragmatiques !

  • Testez ce qui a de la valeur : les fonctionnalités les plus importantes, les plus complexes et les plus utilisées
  • Ne verrouillez pas votre code en testant l’implémentation : testez les fonctionnalités ! Ces tests automatisés seront une force pour la maintenabilité et l’évolutivité du code
  • Challengez les règles, revoyez votre stratégie de test en permanence et n’ayez pas peur de supprimer des tests

La Duck Conf 2025 c'est terminé, à l'année prochaine !