Une suite de tests de quarante minutes peut donner une impression de sérieux : beaucoup de scénarios, un pipeline occupé et un résultat vert avant fusion. Pourtant, si les développeurs la lancent tard, relancent les échecs instables et ne savent pas quel test protège quel risque, sa durée masque une perte de confiance plutôt qu’elle ne la compense.
Le vrai enjeu n’est pas de rendre tous les tests rapides. Il est de raccourcir le délai entre une erreur et une information actionnable. Un test de migration nocturne peut durer vingt minutes et rester précieux ; un parcours navigateur de trois minutes qui répète une règle déjà prouvée et échoue au hasard coûte cher sans apprendre.
Contre-intuitivement, supprimer des tests peut augmenter la sécurité. Lorsque dix scénarios partagent la même préparation fragile, un seul test ciblé au bon niveau, complété par deux assemblages critiques, détecte souvent mieux la causalité. La suppression devient rationnelle si le risque, la preuve de remplacement et la possibilité de retour sont documentés.
Dans une équipe qui maintient une application web métier, le temps de feedback influence directement taille des changements, fréquence d’intégration et diagnostic en production. La méthode reconstruit des boucles fiables sans poursuivre un chiffre de durée universel.
Comprendre pourquoi une suite longue rassure à tort
Le nombre de tests et la durée sont visibles, donc faciles à utiliser comme preuves d’effort. La pertinence l’est moins. Une suite peut vérifier des détails internes, répéter le nominal et ignorer concurrence, droits ou reprise. Le vert confirme alors surtout que le code ressemble encore à ses propres hypothèses.
La lenteur change les comportements. Les commits grossissent, le diagnostic commence après plusieurs sujets, les développeurs utilisent des filtres locaux non représentatifs et les correctifs urgents contournent la CI. Cette causalité doit être observée avant de louer davantage de runners.
Le signal faible apparaît quand « relance la job » devient une procédure. Un autre est l’écart entre la suite complète rarement jouée et les tests réellement utilisés pour développer. Le dispositif officiel n’est plus la source de confiance de l’équipe.
Mesurer attente, signal et coût de diagnostic
La mesure utile sépare durée d’exécution, temps en file, fréquence, taux d’échec, taux d’instabilité et délai jusqu’au test fautif. Une moyenne globale masque la longue traîne. L’équipe observe les percentiles par étape et par type de changement.
Elle relie ensuite les tests aux défauts détectés. Un test long qui a empêché deux régressions critiques peut mériter sa place ; cinquante tests verts depuis deux ans peuvent être de la documentation vivante ou une inertie. La revue qualifie la conséquence, pas seulement le compteur.
Les budgets restent locaux. Par exemple, une équipe peut viser un verdict ciblé sous quatre minutes parce que ses changements arrivent dix fois par jour, puis accepter douze minutes pour la fusion complète. Ces nombres proviennent de sa baseline et sont révisés lorsque l’architecture ou l’organisation change.
Relier chaque test à un risque défendable
Un inventaire léger associe famille de tests, promesse, causalité, niveau et propriétaire. Il ne demande pas une fiche par assertion. Les catégories peuvent être : calcul sensible, permission, transaction, intégration, migration, interface critique et mode dégradé.
Lorsqu’aucun risque ne peut être nommé, l’équipe demande ce qui arriverait si le test disparaissait. S’il ne reste qu’une inquiétude générale, elle peut le désactiver dans une branche de mesure, surveiller les changements couverts et décider avec des faits.
À l’inverse, un scénario rare portant une action irréversible reste prioritaire. La fréquence ne suffit pas à classer. Gravité, détectabilité et coût de reprise expliquent pourquoi un test de clôture annuelle peut rester lent mais bloquant.
Déplacer la preuve vers le niveau le moins coûteux
Une règle de calcul ou de transition se prouve rapidement sans navigateur ni base complète. Une contrainte de transaction demande la vraie base. Un mapping externe bénéficie d’un test de contrat. L’interface ne reste que lorsque navigation, droits, rendu ou assemblage influencent le verdict.
Déplacer ne veut pas dire simuler tout. Le test au niveau inférieur conserve l’invariant ; un petit nombre de tests supérieurs prouve le câblage. Cette combinaison réduit le coût de diagnostic sans laisser chaque couche s’auto-valider.
Le changement se fait par tranche. L’équipe crée la preuve ciblée, casse volontairement la règle pour vérifier qu’elle échoue, puis retire le doublon lent. Le commit documente le risque déplacé et permet de restaurer si une hypothèse était fausse.
Cas concret : ramener une suite de 42 à 12 minutes
Une application de gestion exécute 180 parcours navigateur. Chaque scénario reconstruit un client, se connecte, charge un catalogue et valide une commande. La suite dure quarante-deux minutes sur un runner disponible, dépasse une heure aux heures de pointe et produit plusieurs échecs non reproductibles par semaine.
L’analyse montre que 110 parcours testent surtout des combinaisons de prix. Ces règles deviennent des tests de domaine rapides. Vingt-cinq parcours concernent les droits et passent en tests HTTP avec la vraie configuration de sécurité. Douze parcours restent au navigateur pour navigation, messages et actions JavaScript critiques.
Par exemple, le parcours de commande conserve un cas nominal, un refus de crédit et un double clic. Les intégrations sont pilotées par contrats et fakes. La suite ciblée descend sous trois minutes et la fusion complète sous douze sur cette infrastructure, sans présenter ces seuils comme une norme.
Le gain le plus important n’est pas trente minutes. Un échec pointe désormais vers prix, droit, contrat ou interface. Pendant quatre semaines, les anciens parcours restent disponibles dans une job non bloquante ; aucun risque non couvert n’est découvert, puis ils sont supprimés avec leur préparation coûteuse.
Organiser plusieurs boucles de feedback
Le poste exécute les tests proches du changement. Une sélection déterministe tourne avant push. La CI de fusion ajoute intégrations et assemblages. Les migrations, volumes et compatibilités rares peuvent tourner selon le changement ou sur une boucle plus longue avec un propriétaire d’alerte.
Une boucle différée n’est pas une poubelle. Son échec doit bloquer une promotion, ouvrir un incident ou produire une action claire. Si personne ne regarde le résultat nocturne avant midi, il n’offre pas une protection crédible au déploiement du matin.
La sélection par impact utilise dépendances connues et garde un filet. Un changement de configuration, schéma ou composant partagé déclenche plus large. L’équipe mesure les défauts manqués par la sélection et corrige le graphe au lieu de prétendre qu’il est parfait.
Traiter les tests instables comme des défauts
Un test instable détruit davantage que son temps : il apprend à ignorer le rouge. Chaque instabilité reçoit une occurrence, une cause probable, un propriétaire et une date. La relance automatique peut collecter une preuve, mais elle ne doit pas convertir silencieusement l’échec en succès.
Le seuil de quarantaine est qualifié. Si un test non modifié échoue deux fois sur cinquante exécutions dans cette équipe, il peut quitter la voie bloquante pendant une semaine avec une preuve de remplacement. Une transaction financière ne bénéficie pas forcément de la même tolérance.
Les causes fréquentes sont horloge réelle, ordre, état partagé, attente fixe, ressource limitée et dépendance distante. La correction porte sur l’isolation ou le contrat. Augmenter tous les timeouts masque le symptôme et allonge la suite.
Repenser données, horloge et état partagé
Une fixture globale facilite le début puis crée des dépendances invisibles. Un test modifie un état qu’un autre suppose intact ; le parallélisme révèle l’ordre caché. Les scénarios deviennent petits, nommés et recréables, avec des générateurs déterministes pour les volumes.
L’horloge est injectée lorsqu’une règle dépend du temps. Les identifiants et aléas peuvent recevoir une graine. Les tests ne dorment pas en espérant la fin d’un traitement : ils attendent une condition bornée et affichent l’état observé lors du dépassement.
La base est remise à zéro par transaction, schéma isolé ou reconstruction adaptée au contexte. Le choix mesure coût et fidélité. Une stratégie rapide qui masque les contraintes de la vraie base n’est pas un gain.
Isoler les dépendances sans perdre leur contrat
Les appels partenaires ne doivent pas rendre chaque build dépendant d’une sandbox. Un fake pilotable provoque succès, refus, timeout, quota et doublon. Des tests de contrat vérifient que requêtes et réponses utilisées restent compatibles avec le fournisseur.
Quelques scénarios réels confirment authentification et configuration. Leur indisponibilité produit un verdict d’environnement distinct. Ainsi, une panne externe ne ressemble pas à une régression, et un mock obsolète ne reste pas le seul oracle.
Le test conserve les limites du système : idempotence, ordre, retry et état inconnu. Renvoyer toujours une réponse immédiate rend la suite rapide mais retire précisément la causalité que l’intégration doit gérer.
Limiter les parcours navigateur à leur vraie valeur
Le navigateur prouve ce que les couches inférieures ne voient pas : sélecteurs accessibles, navigation, JavaScript, intégration réelle du formulaire et permissions rendues. Il n’est pas le moyen le plus efficace d’explorer cent combinaisons de règle.
Les parcours se concentrent sur des intentions complètes, avec sélecteurs stables liés au sens plutôt qu’au style. Ils évitent de reproduire chaque clic lorsque l’état peut être préparé par une API de test contrôlée. Cette API respecte les invariants et n’existe pas en production publique.
Les captures, console et réseau sont conservés seulement à l’échec. Le rapport affiche l’étape et les données nommées. Une vidéo de deux minutes sans assertion explicite est moins utile qu’un message qui localise la promesse rompue.
Lire la couverture sans en faire un objectif
La couverture montre le code traversé, pas les comportements prouvés. Une ligne exécutée sans assertion peut être couverte ; une règle d’autorisation critique peut manquer malgré un pourcentage élevé. Le rapport sert à trouver des zones inattendues, puis le risque décide.
Une baisse après suppression n’est pas automatiquement mauvaise si les assertions ont migré vers un contrat plus stable. À l’inverse, une zone financière non couverte demande une explication. Les exclusions restent rares, commentées et revues.
Le mutation testing peut évaluer si certaines assertions détectent une modification, mais il consomme des ressources. L’équipe le cible sur le domaine sensible et interprète les mutants survivants, au lieu de transformer un score supplémentaire en objectif global.
Paralléliser après avoir isolé
Ajouter des runners réduit le mur sans réduire le travail total. Cela convient lorsque les tests sont indépendants et que le temps d’attente bloque réellement le flux. Sinon bases, ports et quotas partagés créent de nouvelles instabilités.
L’équipe isole données, fichiers et identifiants avant d’augmenter la concurrence. Elle équilibre les groupes selon les durées observées et surveille le plus lent. Un découpage fixe par nombre de fichiers peut laisser un runner porter la majorité du coût.
Le budget financier entre dans la décision. Si doubler la capacité gagne une minute rarement utilisée, simplifier les préparations a davantage de valeur. En revanche, un pic prévisible avant livraison peut justifier une capacité temporaire.
Supprimer ou fusionner sans casser la confiance
La suppression commence par les doublons exacts, les tests sans assertion utile et ceux d’une fonctionnalité retirée. Viennent ensuite les scénarios dont le risque est mieux couvert ailleurs. Chaque lot reste petit et observable.
Une période d’ombre exécute l’ancien test sans bloquer. Si lui seul détecte un défaut, l’équipe examine la lacune avant de conclure. L’absence de détection pendant une période n’est pas une preuve absolue, mais complète la revue de risque.
Le rollback est le retour du test ou du groupe, pas le retour de toute la refonte. Le dépôt garde l’historique et la carte de déplacement. Cette réversibilité permet d’agir sans conserver éternellement chaque filet par peur.
Implémenter les budgets et la journalisation
Contrat d’exécution
Les entrées sont la sélection de changements, le niveau de test, les données et la version. Les sorties sont verdict, durée, classe d’échec et artefacts ciblés. Les responsabilités séparent propriétaire du risque, propriétaire du harnais et plateforme CI ; les dépendances et seuils sont versionnés.
La journalisation relie test, runner, tentative et cause sans stocker de secret. Le monitoring distingue file et exécution. Le retry sert au diagnostic, pas au maquillage. En cas de panne d’infrastructure, le repli utilise une capacité connue ou reporte la promotion avec un verdict explicite.
Compatibilité et rollback
Les changements de fixture et schéma conservent une fenêtre compatible avec les branches actives. Le rollback restaure la sélection précédente et les budgets. Le runbook indique comment distinguer régression, instabilité et panne de plateforme avant de relancer.
Préparer reprise et panne du pipeline
Un pipeline est lui-même un service. L’équipe simule runner perdu, cache corrompu, registre indisponible et résultat interrompu après les tests. Elle sait quelles preuves sont réutilisables et lesquelles doivent être recalculées.
Le go ne repose pas sur un statut manuel sans trace. Si la CI est indisponible, un chemin de secours documenté peut exécuter le minimum critique avec approbation et conserver les artefacts. Son usage reste rare et revu.
Après incident, le défaut rejoint le niveau le plus bas capable de reproduire la causalité. La suite apprend du run ; elle ne grossit pas automatiquement d’un parcours bout en bout supplémentaire.
Pour qui cette méthode de réparation est utile
La démarche concerne les produits dont la CI dépasse la capacité d’attention de l’équipe, dont les échecs sont souvent relancés ou dont les correctifs urgents contournent les contrôles. Elle aide aussi après une croissance rapide par accumulation de tests d’interface.
Une petite équipe commence par le top vingt des tests les plus lents et les échecs instables. Une grande organisation travaille par domaine et rend visibles les dépendances partagées. Le programme doit rester proche des développeurs qui diagnostiquent.
Une suite de cinq minutes fiable n’a pas besoin d’un chantier d’optimisation abstrait. L’équipe conserve sa baseline et agit lorsque le feedback ou le coût change, pas parce qu’un outil propose un nouveau tableau.
Erreurs fréquentes lors de l’accélération
- Louer davantage de runners d’abord. Le mur baisse, mais doublons, état partagé et diagnostic restent.
- Tout remplacer par des mocks. La vitesse augmente tandis que transactions et contrats réels disparaissent.
- Relancer automatiquement jusqu’au vert. Le pipeline masque l’instabilité et enseigne à ignorer les signaux.
- Fixer une durée universelle. La bonne boucle dépend de la fréquence, du risque et de l’infrastructure locale.
- Supprimer selon l’ancienneté. Un test rare peut protéger une obligation critique.
- Optimiser sans baseline. L’équipe célèbre une minute gagnée sans savoir si le diagnostic ou les défauts échappés se sont améliorés.
Arbitrer avec une matrice risque-feedback
Si un test couvre une action irréversible et possède une causalité unique, alors il reste bloquant même s’il est long ; l’équipe optimise sa préparation. Si un test répète un invariant déjà prouvé et n’apporte qu’un assemblage banal, il est fusionné ou déplacé.
La matrice croise gravité, unicité de preuve, fréquence d’exécution, instabilité et coût de diagnostic. En revanche, elle ne calcule pas un score automatique. Un propriétaire documente conserver, déplacer, différer ou supprimer.
- À conserver : preuve unique d’un risque critique et diagnostic lisible.
- À documenter : règle déplacée avec son assemblage de remplacement.
- À corriger : test utile mais instable, avec échéance et quarantaine visible.
- À différer : suppression du doublon tant que la période d’ombre n’est pas concluante.
Plan d’action : réparer la suite en huit semaines
Semaines 1 et 2 : établir la carte
L’équipe mesure exécution, file, instabilité et diagnostic sur plusieurs jours. Elle associe les familles de tests aux risques et identifie le top des lenteurs, doublons et préparations partagées. Aucune cible arbitraire n’est annoncée avant cette baseline.
Elle choisit trois parcours critiques et trois douleurs de feedback. Les propriétaires valident ce qui bloquera toujours, ce qui peut passer dans une boucle différée et les conditions de retour.
Semaines 3 à 5 : déplacer et isoler
Les règles combinatoires descendent au domaine, les permissions passent au niveau HTTP et les intégrations utilisent contrats et fakes. Les données deviennent déterministes. Chaque déplacement casse volontairement la règle pour confirmer la nouvelle preuve.
Les tests instables entrent dans une quarantaine visible. Les attentes fixes sont remplacées par des conditions. Le parallélisme est activé sur une tranche isolée, puis son coût et ses collisions sont mesurés.
Semaines 6 à 8 : supprimer et éprouver
Les doublons tournent en ombre avant suppression. L’équipe simule panne de runner et changement de schéma, puis vérifie le chemin de secours. Un collègue extérieur diagnostique trois échecs sans aide du pilote.
La revue compare délai de feedback, instabilité, coût et défauts échappés. Le chantier s’étend seulement si la confiance progresse. Sinon la sélection précédente est restaurée et la causalité manquante devient le prochain objectif.
Le transfert se termine par un exercice chronométré : un développeur hors du pilote modifie une règle, sélectionne les preuves utiles, interprète un échec instable puis restaure la configuration précédente. Toute dépendance à une explication orale ou à un accès privilégié bloque la généralisation et rejoint le backlog de la boucle concernée.
Relier la suite aux scénarios et à l’observabilité
La documentation Symfony sur les tests et la documentation PHPUnit décrivent outils, isolation et organisation. Elles éclairent le mécanisme sans décider du risque local.
Pour relier la suite aux scénarios métier, la collaboration entre QA métier et QA technique fournit le cadre. Le test des workflows à exceptions aide à choisir les cas dégradés, puis leur observabilité ferme le run.
Conclusion : optimiser la connaissance, pas la minuterie
Une suite utile donne rapidement une information fiable et localisée. Sa durée globale compte, mais seulement avec la file, l’instabilité, le diagnostic et les risques qu’elle protège.
Le levier principal est rarement un runner supplémentaire. Déplacer les règles, isoler les données, réduire les parcours navigateur et traiter les tests instables raccourcit le feedback tout en renforçant la causalité.
Commencez par les dix tests les plus lents et les cinq plus relancés. Demandez quelle promesse chacun protège et qui agirait s’il échouait. Les réponses distingueront les preuves à conserver des habitudes coûteuses.
Si votre CI ralentit la livraison sans rassurer le run, Dawap peut vous accompagner pour reconstruire une stratégie de tests adaptée à votre application web métier et à ses risques.