Techniques avancées de positionnement des éléments dans les tests automatisés d'introduction au Web

La dernière fois, j'ai présenté la méthode de gestion des éléments basée sur les fichiers de configuration. Ensuite, le blogueur donnera une explication plus complète sur les méthodes avancées de positionnement de certains éléments. Bien que ces techniques de positionnement avancées n’apparaissent pas fréquemment dans le travail quotidien, elles donnent souvent des résultats inattendus dans certains scénarios où les méthodes de positionnement de base ne peuvent pas être efficaces.

Introduction au positionnement

Les méthodes de positionnement des éléments communs présentées dans les numéros précédents ne seront pas détaillées ici. En fait, dans le processus de conception de scripts de nos tests automatisés Web quotidiens, nous rencontrons souvent des pages Web endommagées en raison des spécifications du code ou des habitudes personnelles des étudiants en développement. Certaines valeurs d'attribut​​des éléments dans sont répétées ou manquantes. À l'heure actuelle, si vous utilisez des méthodes de positionnement d'éléments courantes telles que ID et CLASSNAME, vous ne pourrez souvent pas localiser l'élément souhaité. Ainsi, dans ce numéro, nous nous concentrerons sur les deux méthodes de positionnement CSS Selector et XPath.

Positionnement du sélecteur CSS

Bien que le sélecteur CSS soit également une méthode de positionnement plus couramment utilisée, son taux d'apparition est bien inférieur à celui d'un positionnement tel que l'ID et le nom de classe. En tant que référence pour le positionnement des éléments, nos critères de sélection sont toujours les trois frères que sont l'unicité, la lisibilité et la maintenabilité. Par conséquent, lorsque la méthode de positionnement ordinaire échoue, nous donnerons la priorité au sélecteur CSS, puis à XPath.

CSS Selector localise les éléments via la classe, l'identifiant, le nom de balise, l'attribut, etc. des éléments HTML. En même temps, en raison de ses caractéristiques, cette méthode de positionnement a une grande flexibilité, lisibilité et une grande précision. De plus, précisément en raison de sa lisibilité et de sa précision élevées, sa vitesse d'exécution est également relativement rapide lors de l'exécution de scripts de test.

1. Syntaxe du sélecteur

Comparé à d'autres méthodes de positionnement unique, CSS Selector lui-même couvre la syntaxe de base suivante, qui constitue également une base importante pour notre positionnement combiné ultérieur.

  • Sélecteur de balises : sélectionne les éléments d'un type de balise spécifique. EX:div

  • Sélecteur de classe - Sélectionne les éléments avec un nom de classe spécifique. EX : .class (. signifie sélectionner la classe)

  • Sélecteur d'ID - sélectionne les éléments avec un ID spécifique. EX : #id (# signifie sélectionner l'ID)

  • Sélecteur d'attributs - Sélectionne les éléments avec des attributs spécifiques. EX:[attribut=valeur]

  • Sélecteur d'enfants - sélectionne les éléments enfants directs d'un élément. EX : parent > enfant

  • Sélecteur descendant - sélectionne les éléments descendants d'un élément. EX : ancêtre descendant

2. Positionnement combiné

Après avoir maîtrisé toutes les utilisations des sélecteurs ci-dessus, nous pouvons utiliser des méthodes de combinaison flexibles pour effectuer un positionnement d'éléments à grande vitesse dans le processus de conception de scripts.

[Balise+Catégorie]

Par exemple, nous pouvons combiner les deux attributs du nom de la balise et du nom de la classe. Ici notre code HTML est :

<div class="SignFlow-tab" role="button" tabindex="0">登录</div>

Nous utilisons la combinaison de [tag + class] pour positionner les éléments :

driver.find_element(By.CSS_SELECTOR, "div.SignFlow-tab")

[Balise + Attribut]

Par exemple, le code HTML suivant :

<link data-rh="true" rel="apple-touch-icon" href="https://static.xxx.com/icon-eac.png" sizes="60x60">

Nous utilisons la combinaison de [balise + attribut] pour positionner les éléments :

driver.find_element(By.CSS_SELECTOR, "link[href]")

[Classe + Attribut]

Par exemple, le code HTML suivant :

<input name="digits" type="number" class="Input i7cW1UcwT6ThdhTakqFm" placeholder="输入六位短信验证码" value="">

Nous utilisons la combinaison de [classe + attribut] pour positionner les éléments.

Ce qu'il faut noter ici, c'est que cet élément d'entrée a plusieurs attributs. Ici, trois attributs sont recherchés dans le but de le positionner aussi précisément que possible. Si vous extrayez seulement deux combinaisons ou plus, c'est OK.

driver.find_element(By.CSS_SELECTOR, "input.Input.i7cW1UcwT6ThdhTakqFm[name=digits]")

[progéniture + classe]

L'exemple de code est le suivant :

<div class="SignFlow-tabs">
  <span class="SignFlow-tab" role="button" tabindex="0">密码登录</span>
  <span class="SignFlow-tab" role="button" tabindex="-1">短信登录</span>
</div>

Nous utilisons la combinaison [descendants + classes] pour positionner les éléments.

Ce qu'il faut expliquer ici, c'est qu'en HTML, un élément est contenu par un autre élément, qui est similaire au code HTML ci-dessus. L'élément div le plus externe est l'élément parent et l'élément span est l'élément enfant. Je pense que cela devrait sois bon, comprends. Le sélecteur descendant peut spécifier n'importe quel élément enfant dans l'élément parent, ce qui signifie que ce sélecteur peut sélectionner tous les éléments enfants span sous l'élément div qui ont l'attribut de classe SignFlow-tab.

De plus, que ces sous-éléments span soient directement utilisés comme sous-éléments ou soient imbriqués dans des sous-éléments plus profonds, ils peuvent être spécifiés par des sélecteurs descendants.

driver.find_element(By.CSS_SELECTOR, "div.SignFlow-tabs span.SignFlow-tab")

【Sous+Catégorie】

L'exemple de code est le suivant :

<div class="SignFlow-tabs">
  <span class="SignFlow-tab" role="button" tabindex="0">密码登录</span>
  <span role="button" tabindex="-1">
    <span class="SignFlow-tab">短信登录</span>
  </span>
</div>

Nous utilisons la combinaison de [sub + class] pour positionner les éléments. Pour le sélecteur descendant introduit précédemment, la différence entre le sélecteur enfant et lui réside dans le fait que le sélecteur enfant ne sélectionnera que les éléments enfants directs, tandis que le sélecteur descendant peut sélectionner tous les éléments descendants. Il faut également distinguer l'écriture : les sélecteurs enfants utilisent des ">", tandis que les sélecteurs descendants utilisent des espaces.

driver.find_element(By.CSS_SELECTOR, "div.SignFlow-tabs > span.SignFlow-tab")

Positionnement XPath

1. Positionnement relatif du chemin

Puisque nous ne préconisons pas l’utilisation de chemins absolus pour le positionnement XPath, les chemins relatifs sont naturellement une bonne solution de l’autre côté. Dans la méthode de positionnement de chemin relatif, nous devons spécifier certains mots-clés et symboles pour construire le chemin afin d'obtenir un positionnement précis.

Voici quelques mots-clés de positionnement de chemin que nous utilisons souvent dans la vie quotidienne :

  • . représente le nœud actuel, c'est-à-dire le point de départ du positionnement

  • … représente le nœud parent du nœud actuel

  • // Indique la recherche d'éléments à partir du nœud racine, quelle que soit la position actuelle du nœud.

  • @ représente l'attribut de l'élément

Dire simplement que cela peut être un peu abstrait, regardons donc un exemple correspondant. Le code source d'un certain HTML est le suivant :

<html>
    <head>
        <title>UI自动化测试平台首页</title>
    </head>
    <body>
        <div id="ui_automation_t">
            <h1>这个是标题1</h1>
            <p>这个是测试信息</p>
        </div>
    </body>
</html>

Si nous voulons localiser l'élément label correspondant, notre chemin relatif XPath peut s'écrire comme ceci :

//div[@id='ui_automation_t']/p

Comment comprendre ce chemin relatif ? C'est en fait très simple. Interprétons-le en fonction des mots-clés de chemin relatif ci-dessus.

Tout d'abord, // commence à partir du nœud racine, div recherche tous les éléments div ci-dessous, puis recherche les éléments avec la valeur d'attribut id ui_automation_t dans tous les éléments div, et localise enfin tous les éléments p ci-dessous dans les résultats correspondants. L'avantage du positionnement relatif du chemin est qu'il n'est pas nécessaire de prendre en compte l'impact des changements de chemin d'élément provoqués par des changements structurels, à moins que l'élément lui-même ne change ou ne soit annulé.

2. Utilisation d'opérateurs de chemin relatif

Dans le positionnement de chemin relatif de XPath, nous pouvons également utiliser des opérateurs pour positionner les attributs correspondants. De nombreux jugements conditionnels peuvent être obtenus à l’aide d’opérateurs.

【égal】

Il est facile de comprendre que l'opérateur égal est utilisé pour déterminer si la valeur d'attribut de l'élément est égale à la valeur spécifiée.

driver.find_element(By.XPATH, "//input[@name='discount']")

【Inclure】

La fonction contain() est utilisée pour déterminer si la valeur d'attribut d'un élément contient une chaîne spécifiée.

driver.find_element(By.XPATH, "//input[contains(@class, 'icon-title')]")

【Et ou】

Les deux opérateurs logiques et et ou peuvent être utilisés pour connecter plusieurs expressions.

driver.find_element(By.XPATH, "//input[@name='discount' and @type='content']")

3. Axe

Maintenant que nous parlons de XPath, nous ne pouvons pas contourner le concept "d'axe". Pour parler franchement, il est utilisé pour représenter une grande collection de nœuds dans la page en cours. Maîtriser l'utilisation d'axis peut nous aider à localiser rapidement le nœuds dans la page. Dans les pages complexes, les pages ont souvent des structures imbriquées multicouches. Nous pouvons ignorer certains nœuds non pertinents pour localiser directement les nœuds requis (en évitant la traversée), améliorant ainsi l'efficacité d'exécution du script.

De même, examinons quelques définitions de base liées à l'axe :

  • axe ancêtre - sélectionne tous les nœuds ancêtres du nœud actuel

  • axe descendant - sélectionne tous les nœuds descendants du nœud actuel

  • axe parent - sélectionnez le nœud parent du nœud actuel

  • axe enfant - sélectionne tous les nœuds enfants du nœud actuel

  • axe frère précédent : sélectionne tous les nœuds frères avant le nœud actuel

  • axe suivant-frère - sélectionne tous les nœuds frères après le nœud actuel

  • self axis - sélectionnez le nœud actuel lui-même

【Axe des ancêtres】

Par exemple, il existe le code HTML suivant :

<div class="k_interface">
  <div class="c_app">
    <span class="g_center"></span>
  </div>
</div>

Si nous voulons localiser l'élément ancêtre (parent) de l'élément span, nous pouvons utiliser l'axe ancêtre pour y parvenir :

driver.find_element(By.XPATH, "//span[@class='g_center']/ancestor::div[@class='k_interface']")

L'expression de chemin relatif ci-dessus utilise l'axe ancêtre. L'ancêtre signifie utiliser cet axe pour rechercher l'élément ancêtre sur son nœud après le résultat de positionnement de //span[@class='g_center'], et l'élément ancêtre est désigné comme div [ @class='k_interface'].

Mais une chose à noter ici est que les résultats du positionnement de l'axe sont une collection de nœuds, nous devons donc appeler la méthode find_element lors du positionnement et ne jamais utiliser find_elements. Si nous voulons sélectionner tous les nœuds du nœud, nous pouvons le faire. être obtenu en utilisant l'axe ancêtre-ou-soi. L'utilisation est la même que ci-dessus. Appelez simplement find_element et remplacez l'ancêtre par le mot-clé ancêtre-ou-soi.

【Axe descendant】

L'exemple de code est le suivant :

<div class="k_interface">
  <div class="c_app">
    <span>test_page</span>
  </div>
  <div class="c_app">
    <input id="text" placeholder="Enter your case">
  </div>
  <div class="g_center">
    <button>Submit</button>
  </div>
</div>

Lorsque vous devez localiser les éléments descendants de l'élément k_interface, vous pouvez utiliser l'axe descendant pour y parvenir :

driver.find_element(By.XPATH, "//div[@class='k_interface']//descendant::input[@id='text']")

Si vous devez interroger tous les éléments descendants qui lui sont associés, utilisez plutôt le caractère générique * :

driver.find_element(By.XPATH, "//div[@class='k_interface']//descendant::*")

Les éléments descendants de l'axe descendant ci-dessus sont également similaires aux éléments enfants précédents. Tous les éléments descendants indirects et directs sous son nœud parent peuvent être obtenus.

【Axe parent】

L'exemple de code est le suivant :

<div class="k_interface">
  <p class="c_app">test_index</p>
</div>

Pour trouver l'élément parent d'un élément, nous pouvons utiliser l'axe parent pour y parvenir :

driver.find_element(By.XPATH, "//p[@class='c_app']/parent::div")

Ici, nous obtenons son élément parent div via l'attribut de classe c_app de l'élément p. De même, lorsque vous avez besoin d’obtenir des nombres pluriels, utilisez simplement * pour le représenter.

【Axe enfant】

Il y a le bout de code suivant :

<div class="k_interface">
  <div class="c_app">
    <span class="g_center">test_group_1</span>
  </div>
  <div class="c_app">
    <span class="g_center">test_group_2</span>
  </div>
</div>

Si nous voulons obtenir l'élément test_group_2 sous l'élément div de deuxième niveau sous l'élément parent, nous pouvons utiliser l'axe enfant.

driver.find_element(By.XPATH, "//div[@class='k_interface']/*[2]/*")

Après avoir utilisé l'axe enfant pour l'obtenir, /*[2]/* représente l'élément descendant test_group_2 sous le deuxième élément div.

【frère précédent 轴】

L'exemple de code est le suivant :

<ul>
  <li>Beijing</li>
  <li>Shanghai</li>
  <li class="selected">Guangzhou</li>
  <li>Nanjing</li>
  <li>Jinan</li>
</ul>

Si nous voulons localiser les deux éléments Pékin et Shanghai, nous pouvons utiliser l’expression de chemin suivante.

driver.find_element(By.XPATH, "//li[@class='selected']/preceding-sibling::li[position()<=2]")

//li[@class='selected'] dans le code sélectionnera l'élément Guangzhou, car l'attribut de classe est spécifié ici, puis nous utilisons l'axe frère précédent pour sélectionner tous les éléments frères avant l'élément, plus l'utilisation de li [position()<=2] pour filtrer les deux premiers éléments.

【frère suivant 轴】

Toujours le même code :​​​​​​​

<ul>
  <li>Beijing</li>
  <li>Shanghai</li>
  <li class="selected">Guangzhou</li>
  <li>Nanjing</li>
  <li>Jinan</li>
</ul>

Si nous devons sélectionner les deux éléments Nanjing et Jinan, nous pouvons utiliser l'expression de chemin suivante.

driver.find_element(By.XPATH, "//li[@class='selected']/following-sibling::li")

De même, //li[@class='selected'] n'a pas besoin d'être expliqué. Ici, l'axe des frères et sœurs suivants est utilisé pour sélectionner tous les éléments frères après l'élément. Étant donné que tous les éléments suivants sont sélectionnés ici, il n'est pas nécessaire à préciser Les conditions de localisation sont filtrées, il suffit de préciser directement le nom de la balise.

【auto-axe】

L'exemple de code est le suivant :​​​​​​​

<div id="a_word">
  <p class="selected">The word is a.</p>
</div>

Si nous voulons sélectionner l'élément p ici, nous pouvons directement utiliser l'axe self.

driver.find_element(By.XPATH, "//p[@class='selected']/self::node()")

Le code ci-dessus utilise self::node() pour représenter le nœud actuellement sélectionné, mais il est différent des autres propriétés de l'axe. Généralement, nous l'utilisons directement. Il n'est pas nécessaire d'y consacrer beaucoup de temps.

4. Fonction

Dans la méthode de positionnement de chemin relatif ci-dessus, nous pouvons voir une certaine utilisation de fonctions, telles que position()<=2, etc. En fait, la méthode de positionnement XPath prend en charge une variété de fonctions intégrées. Les fonctions peuvent également nous aider à être plus précis et plus efficaces pour localiser les éléments dont vous avez besoin. Ci-dessous, nous présenterons quelques fonctions intégrées couramment utilisées.

commence avec()

Cette fonction est utilisée pour déterminer si la valeur d'attribut de l'élément commence par la chaîne spécifiée.

driver.find_element(By.XPATH, "//input[starts-with(@id, 'ke')]")

Comme le montre le code ci-dessus, nous utilisons ici start-with pour déterminer si l'attribut id de l'élément commence par ke.

contient()

Cette fonction est utilisée pour vérifier si le contenu du texte dans l'élément contient la chaîne spécifiée.

driver.find_element(By.XPATH, "//div[contains(text(), 'fill')]")

Ici, nous utilisons contain pour vérifier si le contenu du texte de l'élément div contient du remplissage.

sous-chaîne()

Cette fonction est utilisée pour intercepter la partie spécifiée de la chaîne.

driver.find_element(By.XPATH, "//span[substring(text(), 1, 3) = 'key']")

Le code ci-dessus intercepte l'élément span et le contenu intercepté est constitué des trois premiers caractères. La clé = 'ici est utilisée pour comparer les résultats afin de voir si le résultat intercepté est égal au contenu du caractère spécifié. Il convient de noter que le numéro de départ de la correspondance est 1, plutôt que de partir de 0 dans l'indice. Si le résultat de la comparaison ne correspond pas, le résultat de la recherche de cet élément lèvera toujours une exception NoSuchElementException.

compter()

La fonction count est utilisée pour obtenir le nombre d'éléments spécifiés. ​​​​​​​

if driver.find_elements(By.XPATH, "count(//div[@class='advance']) > 1"):
    print("找到了符合条件的元素!")
else:
    print("没有找到符合条件的元素。")

Ici, nous utilisons directement la fonction count pour déterminer le nombre d'éléments et renvoyer les résultats d'impression correspondants.

elements = driver.find_elements(By.XPATH, "count(//div[@class='my-class']) > 1")
if elements:
    print("元素个数大于 1")
else:
    print("元素个数小于等于 1")

La méthode de jugement est arbitraire, mais lorsque vous utilisez la fonction count, vous devez utiliser la méthode find_elements au lieu de find_element.

Points à noter

Ci-dessus sont quelques techniques avancées de positionnement d'éléments de CSS Selector et XPath. Alors, quels sont les points auxquels nous devons prêter attention dans notre travail quotidien ?

Notes sur l'utilisation du sélecteur CSS

Lorsque vous utilisez le sélecteur CSS pour localiser des éléments, essayez d'éviter d'utiliser un certain attribut seul pour le positionnement, tel que les balises div. Il doit y avoir plusieurs éléments sur la page. Leur utilisation seule entraînera le positionnement de plusieurs éléments et ne pourra pas être spécifié, ce qui entraînera une erreur.

Si vous n'êtes pas complètement sûr, essayez d'utiliser le moins possible les caractères génériques * pour le positionnement. Cela correspondra souvent à tous les éléments d'un nœud ou à tous les éléments d'une fonctionnalité spécifiée. Ce résultat est particulièrement terrible lors de l'exécution ou de la maintenance ultérieure du script. étapes.

Vous devez être familier avec la syntaxe du positionnement combiné et des sélecteurs. Vous devez savoir quand utiliser des espaces et quand utiliser des symboles spécifiques. La plupart des caractères du code sont en anglais. Une fois que vous les utilisez de manière incorrecte, ces caractères et espaces deviendra confus lors du dépannage. Plus difficile.

Il y aura également des attributs d'éléments générés dynamiquement dans la page. De nombreux étudiants en développement de tests ont rencontré cela. Nous utilisons généralement des attributs pour faciliter le positionnement.

Certains étudiants aiment utiliser les sélecteurs sous une forme imbriquée, ce qui n'est pas impossible, mais une telle forme de programmation réduira de manière invisible la lisibilité du code lui-même et augmentera le coût de la maintenance ultérieure, ce qui n'en vaut pas la peine.

Remarques sur l'utilisation de XPath

N'utilisez pas de chemins absolus, n'utilisez pas de chemins absolus, n'utilisez pas de chemins absolus, dites les choses importantes trois fois.

Par rapport aux pages contenant plus d'éléments ou des structures plus complexes, utilisez des chemins relatifs et combinez des axes, des opérateurs et des fonctions intégrées pour améliorer la simplicité et la précision des expressions et améliorer la lisibilité du code.

Pour une expression relativement compliquée, vous pouvez essayer de la démonter et de l'exprimer. C'est aussi l'une des techniques pour améliorer l'efficacité de l'exécution des tests.

Vous pouvez vérifier la copie XPath dans les outils de développement du navigateur, mais c'est juste pour référence, et ce n'est pas très pratique.

Enfin : le didacticiel vidéo complet sur les tests de logiciels ci-dessous a été compilé et mis en ligne. Les amis qui en ont besoin peuvent l'obtenir eux-mêmes [garanti 100 % gratuit]

Document d'entretien sur les tests logiciels

"Nous devons étudier pour trouver un emploi bien rémunéré. Les questions d'entretien suivantes proviennent des derniers documents d'entretien de sociétés Internet de premier plan telles que Alibaba, Tencent, Byte, etc., et certains patrons de Byte ont donné des réponses faisant autorité. Après avoir terminé cela Je crois que tout le monde peut trouver un emploi satisfaisant sur la base des informations recueillies lors de l'entretien.

​​​​

Je suppose que tu aimes

Origine blog.csdn.net/weixin_50829653/article/details/132909360
conseillé
Classement