Bugs visuels que vos tests ratent : tester ce que voient vos utilisateurs

Les bugs visuels que vos tests automatisés ratent : pourquoi toBeVisible() et isDisplayed() valident un élément caché ou illisible, et comment tester ce que voit l'utilisateur.

10 min de lecturePar l'équipe de GUI Test Studio

Que sont les bugs visuels ?

Vos tests de bout en bout sont au vert.Puis un client envoie une capture d'écran de la page de paiement : le total de la commande est caché derrière un bandeau promotionnel.Tous les tests automatisés ont réussi, parce que chaque test automatisé interrogeait le code de la page, pas l'écran.Les bugs visuels comme celui-ci sont la raison d'être des tests visuels : ils vérifient ce que vos utilisateurs voient réellement.

Un bug visuel est un défaut que l'on voit à l'écran alors que le code derrière lui semble correct.L'élément existe, il a une taille, il contient le bon texte.Une assertion sur le code réussit.La personne devant l'écran ne peut ni le lire, ni le trouver, ni appuyer dessus.

Cet article montre d'où vient l'écart, quels bugs y tombent, et comment construire des tests de bout en bout qui voient l'écran comme le voient vos utilisateurs.

Votre utilisateur demande

  • Est-ce que je le vois ?
  • Est-ce que je peux le lire ?
  • Est-il là où il devrait être ?
  • A-t-il le même aspect qu'hier ?

Une assertion sur le code demande

  • L'élément est-il dans la page ?
  • A-t-il une taille ?
  • Son style le masque-t-il ?
  • Contient-il le bon texte ?

Ce que « visible » signifie pour Playwright, Cypress et Selenium

Un test de bout en bout codé trouve un élément au moyen d'un sélecteur et vérifie quelque chose à son sujet.L'assertion la plus proche de ce que vit un utilisateur demande si l'élément est « visible ».Chaque outil y répond à sa façon, et aucun ne regarde l'écran.

Playwright

Le toBeVisible() de Playwright réussit quand l'élément a une boîte englobante non vide et aucun style visibility: hidden.Sa documentation ajoute qu'un élément avec opacity: 0 compte comme visible.Il ne demande pas si un autre élément recouvre l'élément, ni de quelle couleur est son texte.

Les actions sont plus strictes que les assertions.Avant un clic, Playwright vérifie que l'élément est bien celui qu'atteint le clic à cet endroit, si bien qu'un bouton recouvert fait attendre le clic jusqu'à l'expiration de son délai.Playwright propose aussi toBeInViewport() pour un élément qui doit se trouver dans la zone d'affichage, et toHaveText() lit par défaut le textContent de l'élément.

Cypress

Depuis Cypress 16, la vérification de visibilité par défaut s'en remet à la méthode Element.checkVisibility() du navigateur lui-même.Un élément compte comme caché quand sa largeur ou sa hauteur est nulle, ou qu'il a display: none, visibility: hidden ou, pour une assertion, opacity: 0.Avant un clic, Cypress vérifie que le centre de l'élément n'est pas recouvert.

Une assertion, c'est une autre affaire.La documentation de Cypress le dit clairement : « L'algorithme moderne ne fait pas de test d'atteinte, il signale donc l'élément recouvert comme visible ».

Selenium

Le isDisplayed() de Selenium n'est pas défini par la spécification W3C WebDriver, en raison de « l'impossibilité de couvrir toutes les conditions possibles », comme le dit la documentation de Selenium.Selenium exécute à la place une grande fonction JavaScript, qui pèse le style de l'élément, sa taille et les ancêtres qui le rognent.Il ne vérifie pas si un autre élément se peint par-dessus, ni si son texte se lit sur son arrière-plan.

Un clic sur un élément recouvert échoue avec une erreur « element click intercepted ».Un élément que le test se contente de lire est toujours signalé comme affiché.

9 bugs visuels qu'une assertion codée laisse passer

Chacun de ces bugs laisse l'élément dans le code de la page, avec une taille et le bon texte.Un test codé qui vérifie que l'élément existe, qu'il est visible ou qu'il contient son texte réussit.Votre utilisateur voit autre chose.

1. Un élément recouvert par un autre

Un bandeau de cookies, un widget de discussion, un en-tête fixe ou une boîte de dialogue qui ne s'est jamais fermée se pose sur l'élément, souvent après un changement de z-index.L'élément reste visible selon toutes les définitions ci-dessus.Un clic dessus est refusé, mais un test qui se contente de le lire, comme un prix, un message d'erreur ou une confirmation, réussit alors que personne ne peut le voir.

2. Un texte que personne ne peut lire

Un texte blanc sur fond blanc, du gris sur du gris après un changement de thème, ou un libellé laissé transparent par une animation défaillante.Aucune vérification de visibilité ne lit une couleur.Le toBeVisible() de Playwright réussit aussi avec opacity: 0.

3. Un texte tronqué

Un libellé trop long pour sa boîte se termine par des points de suspension, ou une hauteur fixe cache la deuxième ligne.La page contient toujours chaque mot, donc une assertion qui lit le texte réussit.Votre utilisateur lit « Confirmez votre co...».

4. Un élément poussé hors de vue

Un tableau plus large ou un titre plus long pousse le bouton Acheter au-delà du bord droit d'un écran étroit.Le bouton garde sa taille, donc toBeVisible() réussit toujours.Le test ne le détecte que s'il demande aussi toBeInViewport() pour ce bouton.

5. La mauvaise image ou la mauvaise icône

Un produit affiche la photo d'un autre produit, une police d'icônes échoue et laisse un carré vide, ou une mise à jour de sprite intervertit deux icônes.L'élément image et la classe de l'icône sont inchangés, donc le code semble correct.

6. Une disposition cassée par un changement CSS

Une seule règle change une marge, une direction flex ou une colonne de grille.Des cartes se chevauchent, une colonne tombe sous une autre, un formulaire perd son alignement.Chaque élément est toujours dans le code, avec son texte et sa taille, donc chaque assertion réussit.

7. Un libellé traduit qui ne tient pas

Les mots allemands ou français sont souvent plus longs que les mots anglais.Un libellé déborde de son bouton, passe sur une deuxième ligne, ou repousse le bouton suivant.La traduction est correcte, donc une assertion de texte réussit dans chaque langue.

8. Une police qui n'a pas pu se charger

Quand une police web ne se charge pas, le navigateur se rabat sur une autre police : les lignes se coupent autrement, et les icônes dessinées avec une police deviennent des carrés vides.Le texte dans le code est le même, donc rien n'échoue.

9. Un indicateur de chargement qui ne s'arrête jamais

Les données arrivent et les lignes sont ajoutées à la page, mais la surcouche de chargement reste par-dessus.Le test trouve ses lignes dans le code et réussit.Votre utilisateur attend devant un indicateur de chargement.

La documentation de Cypress elle-même le résume en une ligne : « une application peut réussir tous les tests fonctionnels et être pourtant livrée visiblement cassée ».

Les tests de régression visuelle par captures d'écran peuvent-ils les détecter ?

Oui, et c'est la réponse habituelle.Les tests de régression visuelle comparent une image de l'écran avec une image de référence prise plus tôt.

Playwright l'intègre avec toHaveScreenshot().Sa documentation prévient que le rendu du navigateur peut varier selon le système d'exploitation hôte, sa version et ses réglages, le matériel et le mode headless.Chaque navigateur et chaque plateforme gardent donc leur propre image de référence.

Cypress prend des captures d'écran, et sa documentation précise qu'il « n'effectue pas lui-même de comparaison d'images ».Des plugins ou des services de tests visuels ajoutent la comparaison.

Des services comme Percy et Applitools Eyes ajoutent des points de contrôle en images à vos tests codés.Percy capture et compare des captures d'écran pendant vos exécutions de tests.Applitools Eyes ajoute un appel de vérification à l'intérieur d'un test.

Dans les deux cas, votre test codé doit toujours atteindre chaque écran et dire quand prendre l'image : c'est vous qui écrivez et maintenez ce code, ses sélecteurs et les images de référence.Une comparaison brute des pixels signale aussi des différences sans conséquence entre machines, si bien que sa tolérance devient un compromis entre fausses alertes et bugs manqués.

Pour voir ces outils côte à côte, consultez l'étude comparative.

Pourquoi les tests manuels ne comblent pas l'écart

Une personne voit chacun de ces bugs au premier coup d'œil.C'est pourquoi beaucoup d'équipes parcourent encore leur application à la main avant une livraison.Les tests manuels ont pourtant leurs limites.

LimiteCe qui se passe
TempsUne passe de régression complète prend des heures, elle se fait donc avant une livraison, pas à chaque build.
AttentionAu vingtième écran de la même passe, l'œil survole.Un petit changement de couleur ou une icône manquante passe inaperçu.
RépétabilitéDeux testeurs regardent des choses différentes, et le même testeur ne regarde pas de la même façon un vendredi soir.Un bug trouvé une fois peut ne plus jamais être recherché.
CouvertureChaque navigateur, appareil et langue multiplie le travail.

Les tests de bout en bout automatisés répètent les mêmes assertions à chaque build sans se lasser.La question est de savoir comment leur faire regarder l'écran comme le fait une personne.

Comment construire des tests de bout en bout qui voient ce que voient les utilisateurs ?

Quel que soit votre outil, six principes font qu'un test de bout en bout vit votre application comme un utilisateur.

  1. 1

    Piloter la vraie application

    Cliquez et saisissez comme le fait une personne, sur le vrai écran.Un test qui ne peut pas appuyer sur un bouton recouvert échoue là où votre utilisateur échouerait.

  2. 2

    Vérifier ce qui est affiché

    Vérifiez l'écran de trois façons : l'image, pour qu'un élément ait la bonne apparence ; les mots, pour qu'il dise la bonne chose ; l'agencement, pour que tout soit à sa place.

  3. 3

    Trouver d'abord l'élément, puis le comparer

    Une fenêtre qui a bougé ou une page qui a défilé n'est pas un bug.Un test doit trouver l'élément là où il se trouve maintenant, puis juger de son apparence.

  4. 4

    Ignorer le bruit, jamais un vrai changement

    Les écrans diffèrent légèrement d'une machine à l'autre, donc la comparaison doit ignorer le bruit de rendu et détecter quand même chaque changement qu'une personne remarquerait.

  5. 5

    Montrer les preuves

    Un échec doit montrer l'écran attendu à côté de celui trouvé, avec le changement signalé, pour que chacun dans l'équipe puisse le lire.

  6. 6

    Limiter le coût du changement

    Quand l'application change volontairement, accepter le nouvel aspect doit prendre un clic, pas une réécriture.

Comment GUI Test Studio teste ce que voient les utilisateurs

GUI Test Studio construit des tests de bout en bout sur ces principes, sans code.Il teste les applications web, les applications de bureau Windows, les téléphones Android et les jeux vidéo avec un seul type de test.Découvrez les tests visuels et les tests GUI avec GUI Test Studio.

Enregistrer le parcours une fois

Dans GUI Test Runner-Recorder, cliquez sur Enregistrer et déroulez le parcours comme vous le faites toujours : il enregistre votre souris, votre clavier et l'écran.Vous pouvez aussi décrire le parcours dans une consigne à Claude, à ChatGPT ou à un modèle d'IA local, l'un des nôtres ou le vôtre, qui l'enregistre pour vous.

Quand vous arrêtez, il demande ce que le test doit vérifier.Avec les réponses par défaut, chaque élément sur lequel vous cliquez ou dans lequel vous saisissez du texte reçoit une assertion visuelle juste avant votre action.Ce qui apparaît de soi-même, comme un menu, une boîte de dialogue ou un message, reçoit une assertion de groupe.

Des assertions sur ce que montre l'écran

AssertionCe dont elle s'assure
Assertion visuelleUn élément est à l'écran et a la bonne apparence : son image, ses couleurs, son icône.
Assertion d'absence visuelleQuelque chose a disparu : un indicateur de chargement, un bandeau, une boîte de dialogue qui doit se fermer.
Assertion de texteLes mots sont les bons, quelle que soit la police ou la couleur.
Assertion de dispositionLes éléments sont à leur place : rien n'a bougé, ne se chevauche ou n'a quitté l'écran.
Assertion de groupePlusieurs assertions d'un même écran au même moment, et en option leur agencement.

Chacune a son guide : assertions visuelles, assertions de texte et assertions de disposition et de groupe.

Trouver l'élément, puis le comparer

Chaque assertion visuelle est décidée en deux phases.La phase de recherche demande si l'élément est à l'écran, et l'attend jusqu'au délai d'attente de l'assertion.Le GTS Engine + AI trouve l'élément en interrogeant d'abord l'application, par ses informations d'accessibilité ou par les propres éléments de la page, et à vue quand l'application ne dit rien.Voir comment GUI Test Studio trouve chaque élément.

La phase de vérification compare ensuite l'élément de près avec sa cible visuelle, l'image que le test attend.Elle ignore ce que l'œil ne peut pas voir, comme l'anticrénelage et la compression vidéo, et détecte quand même les vraies régressions, ce qu'une personne appellerait un changement : un mot différent, une couleur, une icône.

Quand l'élément est trouvé ailleurs que dans l'enregistrement, les clics qui suivent visent l'endroit où il se trouve maintenant.Et un test ne clique jamais à l'aveugle à travers un bandeau : quand l'élément est recouvert, son assertion échoue avant le clic.

Lire ce qui a changé

Après une exécution, le rapport de confiance montre chaque assertion avec l'image attendue à côté de l'image trouvée, le changement mis en évidence, et le verdict en une phrase simple.

L'écran attendu à gauche, celui que l'exécution a trouvé à droite : le bouton semble désactivé et le titre a grandi.

Avec l'analyse intelligente par IA activée, une assertion échouée reçoit aussi un second regard d'une IA, qui dit en mots simples ce qui a changé.Elle fonctionne avec un modèle dans le cloud et votre propre clé, ou avec un modèle d'IA local sur votre propre ordinateur : l'un des nôtres, ou le vôtre.

Quand le changement est voulu, acceptez le nouvel aspect depuis le rapport, et le test l'attend désormais.La ligne de commande, gtr-cli, exécute les mêmes tests depuis n'importe quel pipeline CI/CD, à chaque build.

Quelle assertion détecte quel bug visuel

Les neuf bugs à nouveau, avec l'assertion de GUI Test Studio qui détecte chacun d'eux.

Le bugL'assertionCe que dit le rapport
Un élément recouvert par un autreAssertion visuelleIntrouvable, ou différent : l'écran ne montre plus l'image de l'élément.
Un texte que personne ne peut lireAssertion visuelleDifférent : les couleurs ont changé.
Un texte tronquéAssertion visuelleDifférent : la fin du libellé manque.
Un élément poussé hors de vueAssertion de dispositionL'élément est nommé, avec la distance de son déplacement.
La mauvaise image ou la mauvaise icôneAssertion visuelleDifférent : l'image a changé.
Une disposition cassée par un changement CSSAssertion de disposition, ou assertion de groupe qui vérifie aussi son agencementChaque élément qui a bougé, avec la distance.
Un libellé traduit qui ne tient pasAssertion visuelle, assertion de dispositionDifférent, ou déplacé.
Une police qui n'a pas pu se chargerAssertion visuelleDifférent : les lettres ont changé.
Un indicateur de chargement qui ne s'arrête jamaisAssertion d'absence visuelleToujours à l'écran à l'expiration de son délai.
Une assertion de disposition nomme l'élément qui a bougé et de combien, et propose le réglage qui la ferait tenir.

Là où les assertions codées gardent leur place

Les tests visuels ne remplacent pas vos tests unitaires et vos tests d'API, qui vérifient rapidement la logique et les données, sous l'écran.Une assertion codée qui pose déjà la bonne question, comme un test d'atteinte avant un clic, garde elle aussi sa place.Les tests visuels ajoutent la couche qu'aucun d'eux ne peut voir : l'écran que regardent vos utilisateurs.

Questions

Pourquoi le toBeVisible() de Playwright réussit-il quand un élément est recouvert ?

La vérification de visibilité de Playwright demande seulement si l'élément a une boîte englobante non vide et aucun style visibility: hidden.Elle ne demande pas si un autre élément se trouve par-dessus.Un clic sur cet élément, lui, le vérifie, donc le bug passe entre les mailles quand le test lit l'élément recouvert au lieu de cliquer dessus.

Selenium peut-il détecter un élément caché derrière un autre élément ?

Pas avec isDisplayed(), qui regarde le style, la taille et le rognage d'un élément, jamais ce qui se peint par-dessus.Un clic sur un élément recouvert échoue avec une erreur element click intercepted.Un élément que le test se contente de lire est toujours signalé comme affiché.

Quelle est la différence entre tests visuels et tests fonctionnels ?

Les tests fonctionnels vérifient qu'une fonctionnalité se comporte correctement : un clic mène à la bonne page, un formulaire sauvegarde ses données.Les tests visuels vérifient ce que montre l'écran : les bons éléments, lisibles et à leur place.Un test de bout en bout qui fait les deux détecte ce que vos utilisateurs remarqueraient.

Les tests visuels, est-ce la même chose que la comparaison de captures d'écran ?

Pas tout à fait.Une comparaison brute de captures d'écran signale chaque pixel changé, y compris le bruit de rendu qui diffère d'une machine à l'autre.De bons tests visuels trouvent d'abord chaque élément, ignorent le bruit de rendu sans conséquence tout en détectant les vraies régressions, puis montrent ce qui a changé.

Dois-je écrire du code pour ajouter des assertions visuelles dans GUI Test Studio ?

Non.Vous enregistrez le parcours une fois, et GUI Test Studio ajoute une assertion visuelle avant chaque élément sur lequel vous cliquez ou dans lequel vous saisissez du texte, et vérifie ce qui apparaît à l'écran.Vous ajustez les assertions sur une chronologie visuelle.

Les tests visuels automatisés peuvent-ils remplacer les tests manuels ?

Ils remplacent la partie répétitive : parcourir les mêmes écrans à chaque build.Une personne reste la mieux placée pour juger un nouveau design ou explorer une fonctionnalité pour la première fois.

Selenium, Playwright, Cypress, Percy et Applitools Eyes sont des marques de leurs propriétaires respectifs.

Prêt à enregistrer votre premier test ?

Toutes les fonctionnalités, pendant 15 jours.

Vous préférez le voir sur le type d'application que vous testez ?Réservez un appel gratuit de 30 minutes avec notre équipe.

Réserver une démo