Les tests frontaux automatisés sont géniaux. Nous pouvons écrire un test avec du code pour visiter une page - ou charger un seul composant - et faire cliquer sur les choses ou taper ce texte comme un utilisateur, puis faire des affirmations sur l'état de l'application après les interactions. Cela nous permet de confirmer que tout ce qui est décrit dans les tests fonctionne comme prévu dans l'application.
Étant donné que ce message concerne l'un des éléments constitutifs de tous les tests d'interface utilisateur automatisés, je ne suppose pas trop de connaissances préalables. N'hésitez pas à ignorer les deux premières sections si vous connaissez déjà les bases.
Il existe un modèle classique qui est utile à savoir lors de la rédaction de tests: organiser , agir , affirmer . Dans les tests frontaux, cela se traduit par un fichier de test qui fait ce qui suit:
En spécifiant avec quoi interagir , puis plus tard quoi vérifier sur la page , nous pouvons utiliser divers localisateurs d'éléments pour cibler les parties du DOM que nous devons utiliser.
Un localisateur peut être quelque chose comme l'ID d'un élément, le contenu texte d'un élément, ou un sélecteur CSS, comme .blog-post ou même l'article> div.Container> Div> Div> P: Nth-Child (12). Tout ce qui concerne un élément qui peut identifier cet élément de votre coureur de test peut être un localisateur. Comme vous pouvez probablement le dire déjà à partir de ce dernier sélecteur CSS, les localisateurs sont disponibles dans de nombreuses variétés.
Nous évaluons souvent les localisateurs en termes de fragile ou de stable. En général, nous voulons que les localisateurs des éléments les plus stables possible afin que notre test puisse toujours trouver l'élément dont il a besoin, même si le code autour de l'élément change avec le temps. Cela dit, la maximisation de la stabilité à tout prix peut entraîner une rédaction de test défensive qui affaiblit réellement les tests. Nous obtenons le plus de valeur en ayant une combinaison de fragilité et de stabilité qui s'aligne sur ce que nous voulons que nos tests se soucient.
De cette façon, les localisateurs d'éléments sont comme du ruban adhésif. Ils devraient être très forts dans une direction et se déchirer facilement dans l'autre sens. Nos tests doivent rester ensemble et continuer à passer lorsque des modifications sans importance sont apportées à l'application, mais elles devraient facilement échouer lorsque des changements importants se produisent qui contredisent ce que nous avons spécifié dans le test.
Tout d'abord, prétendons que nous écrivons des instructions pour une personne réelle pour faire son travail. Un nouvel inspecteur de porte vient d'être embauché chez Gate Inspecteurs, Inc. Vous êtes leur patron, et après l'introduction de tout le monde, vous êtes censé leur donner des instructions pour inspecter leur première porte. Si vous voulez qu'ils réussissent, vous ne leur écririez probablement pas une note comme ceci:
Passez devant la maison jaune, continuez jusqu'à ce que vous ayez frappé le champ où la chèvre de l'ami de la mère de Mike a disparu ce temps, puis tournez à gauche et dites-moi si la porte devant la maison en face de vous ouvre ou non.
Ces directions sont un peu comme utiliser un long sélecteur CSS ou XPATH comme localisateur. C'est cassant - et c'est le «mauvais type de fragile». Si la maison jaune est repeinte et que vous répétez les étapes, vous ne trouvez plus la porte et pourriez décider d'abandonner (ou dans ce cas, le test échoue).
De même, si vous ne connaissez pas la situation de la chèvre de la mère de Mike, vous ne pouvez pas vous arrêter au bon point de référence pour savoir quelle porte à vérifier. C'est exactement ce qui fait que le «mauvais type de cassant» est mauvais - le test peut se casser pour toutes sortes de raisons, et aucune de ces raisons n'a rien à voir avec la convivialité de la porte.
Faisons donc un test frontal différent, qui est beaucoup plus stable. Après tout, légalement dans ce domaine, toutes les portes sur une route donnée sont censées avoir des numéros de série uniques du fabricant:
Accédez à la porte avec le numéro de série 1234 et vérifiez s'il s'ouvre.
Cela ressemble plus à la localisation d'un élément par son identifiant. C'est plus stable et ce n'est qu'une étape. Tous les points de défaillance du dernier test ont été supprimés. Ce test n'échouera que si la porte avec cet ID ne s'ouvre pas comme prévu.
Maintenant, il s'avère que deux portes ne devraient pas avoir la même pièce d'identité sur la même route, ce qui n'est pas appliqué nulle part et un jour, une autre porte sur la route se retrouve avec le même identifiant.
Ainsi, la prochaine fois que l'inspecteur de la porte nouvellement embauchée ira à tester «Gate 1234», ils trouvent cet autre en premier, et visitent maintenant la mauvaise maison et vérifient la mauvaise chose. Le test peut échouer, ou pire: si cette porte fonctionne comme prévu, le test passe toujours mais qu'il ne teste pas le sujet prévu. Il donne une fausse confiance. Il continuerait de passer même si notre porte cible d'origine était volée au milieu de la nuit, par des voleurs de porte.
Après un incident comme celui-ci, il est clair que les identifiants ne sont pas aussi stables que nous le pensions. Donc, nous faisons une pensée de niveau suivant et décidons que, à l'intérieur de la porte, nous aimerions une pièce d'identité spéciale juste pour les tests. Nous enverrons une technologie pour mettre l'identification spéciale sur cette seule porte. Les nouvelles instructions de test ressemblent à ceci:
Accédez à la porte avec l'ID de test «My Favorite-Gate» et vérifiez si elle s'ouvre.
Celui-ci est comme utiliser l'attribut de test de données populaire. Les attributs comme celui-ci sont excellents car il est évident dans le code qu'ils sont destinés à être utilisés par des tests automatisés et ne devraient pas être modifiés ou supprimés. Tant que la porte a cet attribut, vous trouverez toujours la porte. Tout comme les identifiants, l'unicité n'est toujours pas appliquée, mais c'est un peu plus probable.
C'est à peu près aussi loin que possible, et cela confirme la fonctionnalité de la porte. Nous ne dépendons de rien, sauf l'attribut que nous avons délibérément ajouté pour les tests. Mais il y a un peu de problème à se cacher ici…
Il s'agit d'un test d'interface utilisateur pour la porte, mais le localisateur est quelque chose qu'aucun utilisateur n'utiliserait pour trouver la porte.
C'est une occasion manquée car, dans ce comté imaginaire, il s'avère que les portes doivent faire imprimer le numéro de maison afin que les gens puissent voir l'adresse. Ainsi, toutes les portes devraient avoir une étiquette unique orientée humaine, et s'ils ne le font pas, c'est un problème en soi.
Lors de la localisation de la porte avec l'ID de test, s'il s'avère que la porte a été repeinte et que le numéro de la maison recouvert, notre test passerait toujours. Mais l'intérêt de la porte est pour les gens d'accéder à la maison. En d'autres termes, une porte de travail qu'un utilisateur ne peut pas trouver devrait toujours être un échec de test, et nous voulons un localisateur capable de révéler ce problème.
Voici une autre passe à cette instruction de test pour l'inspecteur de la porte le premier jour:
Allez à la porte pour la maison numéro 40 et vérifiez si elle s'ouvre.
Celui-ci utilise un localisateur qui ajoute de la valeur au test: cela dépend de quelque chose dont les utilisateurs dépendent également, qui est l'étiquette de la porte. Il ajoute une raison potentielle pour que le test échoue avant qu'il n'atteigne l'interaction que nous voulons réellement tester, ce qui peut sembler mauvais à première vue. Mais dans ce cas, parce que le localisateur est significatif du point de vue d'un utilisateur, nous ne devons pas hausser les épaules comme «cassantes». Si la porte ne peut être trouvée par son étiquette, peu importe si elle s'ouvre ou non - c'est le «bon type de fragile».
De nombreux conseils de tests frontaux nous indiquent d'éviter d'écrire des localisateurs qui dépendent de la structure DOM. Cela signifie que les développeurs peuvent refacter des composants et des pages au fil du temps et permettre aux tests de confirmer que les workflows orientés par les utilisateurs n'ont pas été rompus, sans avoir à mettre à jour les tests pour rattraper la nouvelle structure. Ce principe est utile, mais je le modifierais un peu pour dire que nous devons éviter d'écrire des localisateurs qui dépendent d'une structure DOM non pertinente dans nos tests frontaux.
Pour qu'une application fonctionne correctement, le DOM doit refléter la nature et la structure du contenu qui se trouve à l'écran à tout moment. L'une des raisons est l'accessibilité. Un DOM qui est correct dans ce sens est beaucoup plus facile pour la technologie d'assistance pour analyser correctement et décrire aux utilisateurs qui ne voient pas le contenu rendu par le navigateur. La structure DOM et le vieux HTML ordinaire font une énorme différence pour l'indépendance des utilisateurs qui comptent sur la technologie d'assistance.
Tournons un test frontal pour soumettre quelque chose au formulaire de contact de notre application. Nous utiliserons Cypress pour cela, mais les principes de choix des localisateurs s'appliquent stratégiquement à tous les cadres de tests frontaux qui utilisent le DOM pour localiser les éléments. Ici, nous trouvons des éléments, entrons un test, soumettons le formulaire et vérifions que l'état «merci» est atteint:
//? Pas recommandé cy.get ('# name'). type ('mark') cy.get ('# comment'). Type ('Test Commentaire') cy.get ('. soumi-btn'). cliquez sur () cy.get ('. merci-you'). devrait ('être.Visible')
Il y a toutes sortes d'affirmations implicites dans ces quatre lignes. cy.get () vérifie que l'élément existe dans le DOM. Le test échouera si l'élément n'existe pas après un certain temps, tandis que des actions comme le type et cliquer vérifient que les éléments sont visibles, activés et imprégnés par quelque chose d'autre avant de prendre une action.
Donc, nous obtenons beaucoup «gratuitement» même dans un test simple comme celui-ci, mais nous avons également introduit certaines dépendances sur les choses dont nous (et nos utilisateurs) ne nous soucions pas vraiment. L'ID spécifique et les classes que nous vérifions semblent suffisamment stables, en particulier par rapport à des sélecteurs comme Div.Main> P: Nth-Child (3)> Span.is-a-Button ou autre. Ces longs sélecteurs sont si spécifiques qu'un changement mineur pour le DOM pourrait entraîner l'échec d'un test car il ne trouve pas l'élément , non pas parce que la fonctionnalité est rompue.
Mais même nos courts sélecteurs, comme #Name, sont livrés avec trois problèmes:
Pour les problèmes un et deux, la solution recommandée est souvent d'utiliser des attributs de données dédiés dans notre HTML qui sont ajoutés exclusivement pour les tests. C'est mieux car nos tests ne dépendent plus de la structure DOM, et en tant que développeur modifie le code autour d'un composant, les tests continueront de passer sans avoir besoin d'une mise à jour, tant qu'ils conservent le Data-Test = "Name-Field" attaché à l'élément d'entrée droit.
Cela ne résout pas le problème trois cependant - nous avons toujours un test d'interaction frontal qui dépend de quelque chose qui n'a pas de sens pour l'utilisateur.
Les localisateurs d'éléments sont significatifs lorsqu'ils dépendent de quelque chose dont nous voulons réellement dépendre car quelque chose à propos du localisateur est important pour l'expérience utilisateur. Dans le cas des éléments interactifs, je dirais que le meilleur sélecteur à utiliser est le nom accessible de l'élément. Quelque chose comme ça est idéal:
//? Recommandé cy.getByLabelText ('name'). Type ('Mark')
Cet exemple utilise l'assistance ByLabelText à partir de la bibliothèque de tests Cypress. (En fait, si vous utilisez la bibliothèque de tests sous quelque forme que ce soit, cela vous aide probablement déjà à écrire des localisateurs accessibles comme celui-ci.)
Ceci est utile car maintenant les vérifications intégrées (que nous obtenons gratuitement via la commande cy.type ()) incluent l'accessibilité du champ de formulaire. Tous les éléments interactifs doivent avoir un nom accessible exposé à la technologie d'assistance. C'est ainsi que, par exemple, un utilisateur ScreenReader saurait dans quoi le champ de formulaire dans lequel il tape est appelé afin de saisir les informations nécessaires.
La façon de fournir ce nom accessible pour un champ de formulaire est généralement via un élément d'étiquette associé au champ par un ID. La commande GetByLabelText de la bibliothèque de tests de Cypress vérifie que le champ est étiqueté de manière appropriée, mais aussi que le champ lui-même est un élément autorisé à avoir une étiquette. Ainsi, par exemple, le HTML suivant échouerait correctement avant que la commande type () soit tentée, car même si une étiquette est présente, l'étiquetage d'un div est invalide HTML:
élément div modifiable: <div tenteditable="true"></div>
Parce que c'est un HTML non valide, le logiciel ScreenReader ne pourrait jamais associer correctement cette étiquette à ce champ. Pour résoudre ce problème, nous mettons à jour le balisage pour utiliser un élément d'entrée réel:
Entrée réelle: Label> <input type="text">
C'est génial. Maintenant, si le test échoue à ce stade après les modifications apportées au DOM, ce n'est pas à cause d'une structure non pertinente qui change la façon dont les éléments sont organisés, mais parce que nos modifications ont fait quelque chose pour briser une partie de DOM que nos tests frontaux se soucient explicitement, cela importait réellement pour les utilisateurs.
Pour les éléments non interactifs, nous devons mettre nos plafonds de réflexion. Utilisons un peu de jugement avant de retomber sur les attributs de données ou de tests de données qui seront toujours là pour nous si le DOM n'a pas du tout.
Avant de plonger dans les localisateurs génériques, rappelons-nous: l'état du DOM est notre tout ™ en tant que développeurs Web (au moins, je pense que c'est le cas). Et le DOM conduit l'UX pour tous ceux qui ne vivent pas visuellement la page. Donc, la plupart du temps, il pourrait y avoir un élément significatif que nous pourrions ou devrions utiliser dans le code que nous pouvons inclure dans un localisateur de test.
Et s'il n'y en a pas, parce que. Disons que le code d'application est tous des conteneurs génériques comme Div et Span, nous devons envisager d'abord de corriger le code d'application, tout en ajoutant le test. Sinon, il existe un risque de faire spécifier nos tests que les conteneurs génériques sont attendus et souhaités, ce qui rend un peu plus difficile pour quelqu'un de modifier ce composant plus accessible.
Ce sujet ouvre une boîte de vers sur le fonctionnement de l'accessibilité dans une organisation. Souvent, si personne n'en parle et que cela ne fait pas partie de la pratique dans nos entreprises, nous ne prenons pas l'accessibilité au sérieux en tant que développeurs frontaux. Mais à la fin de la journée, nous sommes censés être les experts de ce qui est le «bon balisage» pour la conception, et ce qu'il faut considérer en décidant. Je discute beaucoup plus de ce côté des choses dans mon discours de Connect.tech 2021, intitulé «Recherche et écriture accessible Vue… Thingies».
Comme nous l'avons vu ci-dessus, avec les éléments que nous considérons traditionnellement comme interactifs, il y a une assez bonne règle de base qui est facile à intégrer dans nos tests frontaux: les éléments interactifs devraient avoir des étiquettes perceptivables correctement associées à l'élément. Donc, tout ce qui est interactif, lorsque nous le testons, doit être sélectionné dans le DOM en utilisant cette étiquette requise.
Pour les éléments que nous ne considérons pas comme interactifs - comme la plupart des éléments de rédaction de contenu qui affichent des éléments de texte de quoi que ce soit, à part certains repères de base comme Main - nous ne déclencherions pas d'échecs d'audit de phare si nous mettons l'essentiel de notre contenu non interactif dans des conteneurs génériques Div ou Span. Mais le balisage ne sera pas très informatif ou utile pour la technologie d'assistance car il ne décrit pas la nature et la structure du contenu à quelqu'un qui ne peut pas le voir. (Pour voir cela pris à l'extrême, consultez l'excellent article de blog de Manuel Matuzovic, "Construire le site le plus inaccessible possible avec un score de phare parfait.")
Le HTML que nous rendons est l'endroit où nous communiquons des informations contextuelles importantes à quiconque ne perçoit pas visuellement le contenu. Le HTML est utilisé pour construire le DOM, le DOM est utilisé pour créer l'arborescence d'accessibilité du navigateur, et l'arborescence d'accessibilité est l'API que les technologies d'assistance de toutes sortes peuvent utiliser pour exprimer le contenu et les actions qui peuvent être prises à une personne handicapée à l'aide de notre logiciel. Un chef de script est souvent le premier exemple auquel nous pensons, mais l'arbre d'accessibilité peut également être utilisé par d'autres technologies, comme des écrans qui transforment les pages Web en braille, entre autres.
Les vérifications automatisées d'accessibilité ne nous indiquent pas si nous avons vraiment créé le bon HTML pour le contenu. La «justesse» du HTML un jugement que nous faisons des développeurs sur les informations dont nous pensons doivent être communiquées dans l'arbre d'accessibilité.
Une fois que nous avons passé cet appel, nous pouvons décider dans quelle mesure cela est approprié pour cuisiner dans les tests frontaux automatisés.
Disons que nous avons décidé qu'un conteneur avec le rôle de statut Aria tiendra le «merci» et la messagerie d'erreur pour un formulaire de contact. Cela peut être bien pour que les commentaires du succès ou de l'échec du formulaire puissent être annoncés par un lecteur ScreenReder. Les classes CSS de .Meug-You et .Error pourraient être appliquées pour contrôler l'état visuel.
Si nous ajoutons cet élément et que nous voulons écrire un test d'interface utilisateur pour cela, nous pourrions écrire une affirmation comme celle-ci après que le test remplisse le formulaire et le soumet:
//? Pas recommandé cy.get ('. merci-you'). devrait ('être.Visible')
Ou même un test qui utilise un sélecteur non brittle mais toujours dénué de sens comme celui-ci:
//? Pas recommandé cy.get ('[Data-test]'). devrait ('be.visible')
Les deux pourraient être réécrits à l'aide de cy.Contains ():
//? Recommandé cy.Contains ('[role = "statut"]', 'Merci, nous avons reçu votre message') .Should ('be.visible')
Cela confirmerait que le texte attendu est apparu et était à l'intérieur du bon type de conteneur. Par rapport au test précédent, cela a beaucoup plus de valeur en termes de vérification des fonctionnalités réelles. Si une partie de ce test échoue, nous voudrions le savoir, car le message et le sélecteur d'éléments sont importants pour nous et ne devraient pas être modifiés trivialement.
Nous avons définitivement acquis une couverture ici sans beaucoup de code supplémentaire, mais nous avons également introduit un autre type de fragilité. Nous avons des cordes anglaises simples dans nos tests, et cela signifie que si le message «merci» change en quelque chose comme «Merci d'avoir tendu la main!» Ce test échoue soudainement. Idem avec tous les autres tests. Un petit changement dans la façon dont une étiquette est écrite nécessiterait de mettre à jour tout test qui cible les éléments à l'aide de cette étiquette.
Nous pouvons améliorer cela en utilisant la même source de vérité pour ces chaînes lors de tests frontaux que nous le faisons dans notre code. Et si nous avons actuellement des phrases lisibles par l'homme intégrées juste là dans le HTML de nos composants… eh bien maintenant, nous avons une raison de retirer ces trucs de là.
Un nombre magique (ou moins excitant, une «constante numérique sans nom») est cette valeur super spécifique que vous voyez parfois dans le code qui est important pour le résultat final d'un calcul, comme un bon vieux 1.023033 ou quelque chose. Mais comme ce nombre n'est pas non étiqueté, sa signification n'est pas claire, et il n'est donc pas clair ce qu'elle fait. Peut-être que cela applique une taxe. Peut-être que cela compense un bug que nous ne connaissons pas. Qui sait?
Quoi qu'il en soit, il en va de même pour les tests frontaux et le conseil général est d'éviter les chiffres magiques en raison de leur manque de clarté. Les avis de code les attraperont souvent et demanderont à quoi sert le nombre. Pouvons-nous le déplacer dans une constante? Nous faisons également la même chose si une valeur doit être réutilisée plusieurs endroits. Plutôt que de répéter la valeur partout, nous pouvons le stocker dans une variable et utiliser la variable selon les besoins.
En écrivant des interfaces utilisateur au fil des ans, je suis venu voir du contenu texte dans des fichiers HTML ou de modèle comme très similaires aux nombres magiques dans d'autres contextes. Nous mettons des valeurs absolues tout au long de notre code, mais en réalité, il pourrait être plus utile de stocker ces valeurs ailleurs et de les apporter au moment de la construction (ou même via une API en fonction de la situation).
Il y a plusieurs raisons à cela:
{{Content [currentLanguage] .ContactForm.Name}} label>
const text = content.en.contactFrom // Nous le ferions une fois et tous les tests dans le fichier peuvent en lire cy.Contains (text.nameLabel, '[role = "statut"]'). devrait ('be.visible')
Chaque situation est différente, mais avoir un système de constantes pour les cordes est un atout énorme lors de la rédaction de tests d'interface utilisateur robustes, et je le recommanderais. Ensuite, si et quand la traduction ou le contenu dynamique devient nécessaire pour notre situation, nous sommes beaucoup mieux préparés.
J'ai également entendu de bons arguments contre l'importation de chaînes de texte dans les tests. Par exemple, certains tests sont plus lisibles et généralement meilleurs si le test lui-même spécifie le contenu attendu indépendamment de la source de contenu.
C'est un point juste. Je suis moins persuadé par cela parce que je pense que le contenu devrait être contrôlé par le biais d'un modèle de revue / publication éditoriale, et je veux que le test vérifie si le contenu attendu de la source a été rendu, pas des chaînes spécifiques qui étaient correctes lorsque le test a été écrit. Mais beaucoup de gens sont en désaccord avec moi à ce sujet, et je dis que dans une équipe, le compromis est compris, l'un ou l'autre choix est acceptable.
Cela dit, c'est toujours une bonne idée d'isoler le code du contenu dans le frontal plus généralement. Et parfois, il peut même être valable de mélanger et de faire correspondre - comme l'importation de chaînes dans nos tests de composants et de ne pas les importer dans nos tests de bout en bout. De cette façon, nous enregistrons une duplication et gagnons en toute confiance que nos composants affichent un contenu correct, tout en ayant des tests frontaux qui affirment indépendamment le texte attendu, dans le sens éditorial orienté utilisateur.
Les sélecteurs CSS comme [Data-Test = "Success-Message"] sont toujours utiles et peuvent être très utiles lorsqu'ils sont utilisés de manière intentionnelle, au lieu d'être utilisés tout le temps. Si notre jugement est qu'il n'y a pas de moyen significatif et accessible de cibler un élément, les attributs de test de données sont toujours la meilleure option. Ils sont bien meilleurs que, disons, en fonction d'une coïncidence, comme la structure DOM se trouve le jour où vous écrivez le test et retombe dans le style de test de la «deuxième liste de la troisième div avec une classe de carte».
Il y a aussi des moments où le contenu devrait être dynamique et il n'y a aucun moyen de saisir facilement les chaînes d'une source de vérité commune à utiliser dans nos tests. Dans ces situations, un attribut de test de données nous aide à atteindre l'élément spécifique qui nous intéresse. Il peut toujours être combiné avec une affirmation adaptée à l'accessibilité, par exemple:
cy.get ('h2 [data-test = "intro-subdication"]')
Ici, nous voulons trouver ce qui a l'attribut de test Data-Test de la soumission d'introduction, mais permettez à notre test d'affirmer qu'il devrait être un élément H2 si c'est ce que nous nous attendons. L'attribut de test de données est utilisé pour s'assurer que nous obtenons le H2 spécifique qui nous intéresse, pas un autre H2 qui pourrait être sur la page, si pour une raison quelconque, le contenu de ce H2 ne peut pas être connu au moment du test.
Même dans les cas où nous connaissons le contenu, nous pourrions toujours utiliser des attributs de données pour nous assurer que l'application rend ce contenu au bon endroit:
cy.Contains ('H2 [Data-Test = "Intro-Subheding"]', 'Bienvenue à Tester!')
Les sélecteurs de tests de données peuvent également être une commodité pour atteindre une certaine partie de la page, puis faire des affirmations à l'intérieur. Cela pourrait ressembler à ce qui suit:
cy.get ('Article [Data-Test = "Ablum-Card-Blur-Great-Escape"]'). Au sein (() => { cy.Contains ('H2', 'The Great Escape'). devrait ('être.Visible') cy.Contains ('p', '1995 album by blur'). devrait ('be.visible') cy.get ('[Data-Test = "Stars"]'). devrait ('have.length', 5) })
À ce stade, nous entrons dans une certaine nuance car il peut très bien y avoir d'autres bonnes façons de cibler ce contenu, ce n'est qu'un exemple. Mais à la fin de la journée, c'est un bon s'il se soucie de détails comme celui-ci, car au moins nous avons une certaine compréhension des fonctionnalités d'accessibilité intégrées dans le HTML que nous testons, et que nous voulons les inclure dans nos tests.
Les tests frontaux nous apportent beaucoup plus de valeur si nous réfléchissons à la façon dont nous disons aux tests avec quels éléments interagir et à quoi s'attendre. Nous devons préférer les noms accessibles pour cibler les composants interactifs, et nous devons inclure des noms d'éléments spécifiques, des rôles ARIA, etc., pour un contenu non interactif - si ces choses sont pertinentes pour la fonctionnalité. Ces localisateurs, lorsqu'ils sont pratiques, créent la bonne combinaison de force et de fragilité.
Et bien sûr, pour tout le reste, il y a un test de données.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!