Un meilleur filtre pour vos tests UI automatisés

Classez les parcours selon le temps qu'une panne mettrait à être repérée, pas selon leur importance. Un export, une invitation, une page de paramètres, un récapitulatif programmé. Chacun compte pour quelqu'un, et aucun n'est surveillé par la foule : une régression peut donc y rester un mois.

Deuxième filtre : à quelle fréquence le parcours change. Un écran redessiné à chaque sprint coûtera plus en maintenance qu'il ne rapporte. Couvrez-le une fois qu'il s'est stabilisé.

Les trois coûts

Les sélecteurs

  • Une refonte qui ne change rien de fonctionnel fait passer la suite au rouge.

  • Là où part réellement l'essentiel du temps de maintenance.

L'attente

  • Les délais fixes sont lents et restent instables. Une attente correcte suppose de savoir quoi attendre.

  • C'est de là que vient l'essentiel de l'instabilité.

La couverture rédigée à la main

  • Vous couvrez ce que quelqu'un a écrit, c'est-à-dire les parcours intéressants plutôt que ceux qui cassent.

Les deux premiers se traitent avec de la discipline. Le troisième est structurel : la couverture rédigée à la main est limitée par le temps de celui qui l'écrit, et ce temps n'augmente pas.

Trois habitudes qui font gagner le plus

  • Ancrez-vous sur des attributs stables. Un attribut de test dédié plutôt qu'un chemin CSS. À lui seul, cela élimine l'essentiel des casses liées aux refontes.

  • Attendez un état, jamais un délai. Attendez l'élément ou la réponse. Un délai fixe est à la fois lent et peu fiable.

  • Vérifiez ce qu'un rechargement confirmerait. Une notification de succès ne prouve pas que quoi que ce soit a été enregistré.

Pourquoi les suites finissent supprimées

Pas parce qu'elles ne trouvent rien. Parce que le rapport entre vrais échecs et échecs de maintenance se dégrade au point que plus personne ne lit les résultats. Dès qu'un build rouge veut dire « sans doute un sélecteur » plutôt que « sans doute un bug », la suite a cessé de fonctionner, même si elle continue de s'exécuter.

Préserver ce rapport, c'est le vrai travail, et cela dépend davantage de la façon dont les étapes sont exprimées que du nombre de tests que vous avez.

Une couverture qui ne dépend pas du temps de rédaction

Des étapes exprimées comme des intentions survivent aux changements cosmétiques, et une couverture générée à partir du produit plutôt que de la mémoire de quelqu'un inclut des parcours que personne n'aurait écrits. C'est la part du coût que la discipline ne peut pas corriger.

Terminal

npm install -g @testsprite/testsprite-cli
testsprite setup

Le tableau de bord fait la même chose pour ceux qui ne veulent pas d'installation locale, et l'ensemble des commandes disponibles se trouve dans le dépôt du CLI.

La taille de suite qui reste utile

Il existe une taille au-delà de laquelle une suite navigateur coûte plus qu'elle ne rapporte, et elle est plus petite que la plupart des équipes ne l'imaginent.

La contrainte n'est pas le temps d'exécution, c'est l'attention. Une suite de trente parcours produit des échecs sur lesquels quelqu'un enquête. Une suite de trois cents produit une liste quotidienne, et une liste se trie au lieu de se lire. Dès que le tri commence, le test supplémentaire ajoute du bruit et non de la couverture, aussi bien écrit soit-il.

La bonne question, au moment d'ajouter un test, n'est donc pas de savoir si le parcours compte. C'est de savoir si vous enquêteriez sur son échec un vendredi après-midi. Si la réponse honnête est que vous le relanceriez avant de passer à autre chose, le test est déjà du bruit et l'écrire dégrade la suite.

Lancez-la à chaque changement

Le déclencheur compte plus que le mécanisme. La brancher sur votre événement de déploiement fait que chaque changement est vérifié sans que personne n'ait à le décider ; la GitHub App s'en charge depuis le tableau de bord, et une étape GitHub Actions le fait depuis votre workflow.

Là où TestSprite change le calcul

Le troisième coût, cette couverture limitée par le temps de rédaction, est celui que la discipline ne peut pas corriger, et c'est celui que TestSprite supprime. Les cas sont générés à partir de votre produit et affinés en langage naturel : les parcours discrets sont donc couverts sans que personne n'ait à dégager un après-midi pour les écrire.

Les deux premiers coûts s'améliorent par effet de bord. Les étapes sont stockées comme des intentions plutôt que comme des chemins dans le DOM : une refonte qui déplace un bouton ne fait donc pas passer la suite au rouge, et l'attente est prise en charge au lieu d'être réglée test par test. C'est dans ces deux postes que part l'essentiel du temps de maintenance.

Ce que cela préserve, c'est le chiffre qui décide de la survie d'une suite : la part de builds rouges qui correspondent à de vrais bugs. Maintenez-la haute et l'on continue de lire les résultats, ce qui fait toute la différence entre une vraie couverture et un job qui tourne chaque nuit.

Combien de tests UI faut-il avoir ?

Moins que vous ne le pensez, et choisis selon la discrétion avec laquelle une panne passerait inaperçue. Une petite suite en laquelle on a confiance vaut mieux qu'une grande que l'on ignore.

Quel taux de réussite est-il raisonnable d'accepter ?

En dessous d'un taux très élevé, plus personne ne lit les résultats. Traquer les derniers pourcents d'instabilité rapporte plus que d'ajouter de nouveaux tests.

Les tests UI doivent-ils s'exécuter à chaque commit ?

À chaque pull request : c'est généralement la bonne réponse. À chaque commit, c'est souvent trop lent pour être utile, et on finit par les désactiver.

Et la régression visuelle ?

Un sujet à part, avec son propre problème de tolérance. Utile pour les design systems, bruyant pour les écrans applicatifs.

Les tests manuels sont-ils encore nécessaires ?

Pour l'exploratoire et pour tout ce qui demande de juger si quelque chose sonne juste, oui. Pour répéter les mêmes vérifications, non.

En résumé

Couvrez ce qui casserait sans bruit.

Les tests UI automatisés doivent être choisis selon le temps qu'une panne resterait invisible, plutôt que selon l'importance. Ancrez-vous sur des attributs stables, attendez un état, vérifiez ce qu'un rechargement confirme et préservez le rapport entre vrais échecs et bruit de maintenance.