Un build rouge est rarement un bug. C’est un sélecteur fragile, une pause fixe, une donnée partagée, un environnement qui dérive ou un échec sans responsable. Ce que font les bonnes équipes, et ce qu’un agent peut corriger, ou non.
Le scénario est connu. Une version part, l’exécution suivante revient rouge, et quelqu’un passe la matinée à séparer les vrais échecs du bruit. Le plus souvent, le produit fonctionne : une classe a été renommée, une page a mis une seconde de plus à charger, deux tests partageaient un compte, ou la préproduction était en plein déploiement. La suite n’a pas trouvé de bugs. Elle a trouvé du changement.
Les tests end-to-end vérifient le produit comme un client l’utilise. C’est ce qui fait leur valeur, et leur fragilité : ils dépendent de tout à la fois. Les causes sont rarement mystérieuses. Une partie des remèdes tient à l’outillage ; l’essentiel tient aux habitudes.
Des sélecteurs liés à la structure de la page
Un test scripté trouve les éléments d’après la façon dont le code est construit : un chemin CSS, un nom de classe généré, le troisième bouton d’un formulaire. Rien de tout cela n’est ce que voit l’utilisateur. Un refactor qui ne change rien pour les clients, comme une nouvelle bibliothèque de composants ou un bouton déplacé dans une fenêtre modale, casse le test quand même.
Les bonnes équipes traitent les localisateurs comme un contrat. Elles ciblent ce que l’utilisateur perçoit, un rôle et un nom accessibles ou un libellé visible, ajoutent des attributs de test là où rien de stable n’existe, et gardent chaque localisateur à un seul endroit. Cela marche, mais demande de la discipline à chaque équipe front, et cela casse encore dès qu’un parcours est repensé.
Attendre une durée plutôt que la page
Les pauses fixes sont l’autre grand classique. Une pause de trois secondes est trop longue un jour calme et trop courte sur un runner de CI chargé. Les fronts modernes ajoutent leurs propres situations de concurrence : un bouton affiché avant que son gestionnaire d’événements soit branché, une liste qui se remplit en retard, un message qui disparaît avant l’assertion.
Le remède consiste à attendre une condition, jamais une durée : l’élément visible et actif, la réponse reçue, le texte affiché. Et avant d’allonger un délai, regardez la page. Une étape qui demande huit secondes est un problème de performance, et vos utilisateurs attendent aussi.
Un agent ne rend pas non plus une page lente plus rapide : dans Qalion, une exécution qui dépasse sa limite de temps se termine en Erreur, avec le motif « Délai dépassé ».
Des données que les tests se partagent
Beaucoup de tests instables sont des problèmes de données déguisés. Le test B attend le panier rempli par le test A. Un code promo ne sert qu’une fois. Lancez la suite en parallèle, et deux tests modifient le même utilisateur au même instant. On obtient l’échec le plus déroutant qui soit : le test passe seul et échoue dans la suite.
Les bonnes équipes font en sorte que chaque test possède ses données. Chacun crée ce dont il a besoin, avec des valeurs propres à l’exécution, ou utilise un compte que personne d’autre ne touche, et ne compte jamais sur un test passé avant lui. Préparer l’état par une API ou un script d’initialisation est plus rapide et plus fiable que de cliquer dans l’interface.
Qalion couvre une partie de ce travail. Les jeux de données fournissent les valeurs d’un cas, par environnement si besoin, et les colonnes secrètes donnent au modèle un marqueur à la place de l’identifiant. Chaque exécution démarre dans un navigateur neuf : cookies et stockage ne passent pas d’un test à l’autre. Qalion ne réinitialise pas votre base de données pour autant : deux exécutions connectées au même compte au même moment entreront toujours en collision.
Des environnements et des services que vous ne maîtrisez pas
La préproduction est rarement une copie de la production. Les feature flags diffèrent, la configuration dérive, une autre équipe déploie en pleine exécution, un bandeau de consentement n’apparaît que sur un environnement, un fuseau horaire fait échouer un test autour de minuit. Viennent ensuite les services que vous n’exploitez pas, des sandboxes de paiement aux services de cartographie, captchas et envois d’e-mails : chacun peut être lent ou indisponible le jour où vous testez.
Les bonnes équipes font de l’environnement une partie du résultat. Chaque exécution indique l’environnement et le build visés, les flags sont figés par environnement, les déploiements sont coordonnés avec les exécutions, et un service qui n’est pas testé est simulé. Surtout, elles distinguent « le site n’a pas répondu » de « le produit ne fonctionne pas ».
Qalion trace cette frontière dans ses verdicts. Échoué signifie que l’agent a jugé que l’application ne faisait pas ce qui était attendu. Erreur signifie qu’il n’a jamais atteint de verdict : site injoignable, délai dépassé, agent bloqué. Les erreurs sont exclues des taux de réussite. Les cookies, éléments de stockage, en-têtes et identifiants d’authentification basique dont un site a besoin sont posés par code avant le chargement de la première page, et chaque exécution garde son journal réseau et la console du navigateur.
Rien de tout cela ne rend stable un environnement instable. Si la préproduction tombe deux fois par semaine, c’est la préproduction qu’il faut réparer.
Des tests qui enregistrent des clics plutôt qu’une intention
Un script enregistré capture comment un parcours a été cliqué, pas pourquoi. « Cliquer sur le troisième bouton, saisir dans le deuxième champ » ne dit à personne ce que le test protège : chaque échec commence par un travail d’archéologie. Les assertions en pâtissent aussi : certaines ne vérifient rien, d’autres comparent une page entière et échouent au moindre changement.
Les bonnes équipes écrivent un comportement par test et font de chaque résultat attendu quelque chose qu’une personne peut voir : un message, un titre, un total. Les étapes disent ce que fait l’utilisateur, « ajouter les chaussures bleues au panier », et la mécanique reste hors du test.
C’est là qu’un agent change le plus de choses. Un cas de test Qalion s’écrit en langage naturel, sous forme d’étapes, de scénario Gherkin ou de texte libre. À chaque étape, l’agent regarde une capture de la page où les éléments interactifs sont repérés, choisit celui que décrit l’étape et agit, puis compare la page au résultat attendu et enregistre un verdict. Les classes et ID renommés, les éléments déplacés et la plupart des refactors qui conservent l’intention de l’utilisateur ne cassent donc plus le cas.
C’est ce que recouvre l’auto-réparation dans Qalion, et elle a une limite voulue : elle porte sur la façon de trouver un élément, jamais sur ce que fait le produit. Un total de commande faux échoue toujours. Un parcours modifié, par exemple avec une nouvelle étape obligatoire, impose de mettre le cas à jour, vous-même ou via Qalion AI, qui propose la modification et attend votre validation. Et chaque verdict s’accompagne de quoi le vérifier : une capture par étape, une vidéo et le journal des actions de l’agent.
Des échecs dont personne ne s’occupe
La dernière cause n’est pas technique. Quand un résultat rouge n’a pas de responsable, on relance jusqu’au vert, les relances automatiques masquent l’instabilité et les échecs connus s’accumulent. Puis un vrai bug fait passer le build au rouge, et personne ne réagit, parce que le rouge ne veut plus rien dire.
Les bonnes équipes donnent à chaque échec un responsable dans la journée, et une cause : bug produit, test, données ou environnement. Les tests instables sont mis en quarantaine au grand jour, avec un nom et une échéance, au lieu d’être relancés en silence. Les problèmes connus portent une raison et une date d’expiration.
Qalion est construit autour de cette routine :
- Les exécutions en échec ne sont pas relancées automatiquement. Une relance crée une nouvelle tentative dans la même exécution, et les tentatives précédentes restent comme preuves.
- Les échecs sont regroupés en problèmes par cas de test, étape en échec et type d’échec, l’IA se chargeant du reste. Dix exécutions rouges dues à un même bug forment un seul problème, avec un responsable, un état et une catégorie, comme bug produit, données de test ou environnement.
- Un test est signalé comme instable après au moins deux bascules entre succès et échec sur ses dix dernières exécutions, dès qu’il compte au moins six verdicts. Un test en quarantaine continue de s’exécuter, mais ne compte plus dans les taux de réussite. Ces chiffres viennent de règles fixes, pas de l’IA.
- Quand une cause n’est pas claire, une analyse par IA lit les preuves, dont la dernière exécution réussie, et cite ce sur quoi elle s’appuie.
Par où commencer
Comptez avant de corriger. Prenez les cinq parcours qui cassent le plus souvent, en général la connexion, le paiement et votre formulaire principal, exécutez-les chaque jour pendant deux semaines et classez chaque résultat rouge : bug produit, test, données ou environnement. La part de vrais bugs est la mesure honnête de votre suite. La plus grosse des autres catégories vous dit où porter l’effort en premier.
Si ce sont les données, donnez à chaque test les siennes. Si c’est l’environnement, réparez l’environnement. Si ce sont les localisateurs et les scripts, réécrivez ces parcours en intentions. Et donnez un responsable à chaque échec dès le premier jour.
Un agent qui lit la page supprime une catégorie de bruit, le localisateur cassé, et rend les autres plus faciles à voir. Il ne rend pas stable un environnement instable, et il ne doit jamais faire passer au vert une vraie régression.