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 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.
À 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.
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.
Antoine nous rappelle qu’il est important de tester le code de production pour :
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” .
Une stratégie de test est indispensable afin d’orienter la manière dont une application est testée. Elle définit :
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.
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.
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 :
Une fois le test posé, l’équipe a pu refactorer le code en s’assurant que la logique fonctionnelle était toujours valide.
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 :
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. En complément de cette matrice, Antoine nous propose également de poser des tests :
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 :
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.
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é.
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.
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.
Dans le contexte du Chaostrateur, l’équipe a redéfini sa stratégie de test pour arriver à :
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%) |