web-dev-qa-db-fra.com

Quelle est la différence entre css Selector et Xpath et quelle est la meilleure en termes de performances pour les tests entre navigateurs?

Je travaille avec Selenium WebDriver 2.25.0 sur une application Web multilingue et teste principalement le contenu de la page (pour différentes langues telles que l'arabe, l'anglais, le russe, etc.).

Pour mon application, qui est meilleur en fonction des performances, assurez-vous que tous les navigateurs sont pris en charge (par exemple, IE 7,8,9, FF, Chrome, etc.).

Merci d'avance pour vos précieuses suggestions.

53
Chetan

Les sélecteurs CSS fonctionnent beaucoup mieux que Xpath et cela est bien documenté dans la communauté Selenium. Voici quelques raisons,

  • Les moteurs Xpath sont différents dans chaque navigateur, ce qui les rend incohérents
  • IE ne possède pas de moteur xpath natif. Par conséquent, Selenium injecte son propre moteur xpath pour la compatibilité de son API. Par conséquent, nous perdons l’avantage d’utiliser les fonctionnalités de navigateur natif que WebDriver promeut par nature.
  • Xpath a tendance à devenir complexe et donc difficile à lire à mon avis

Cependant, dans certains cas, vous devez utiliser xpath, par exemple, pour rechercher un élément parent ou un élément à l'aide de son texte (je ne recommanderais pas cette option).

Vous pouvez lire le blog de Simon ici . Il recommande également CSS sur Xpath.

Si vous testez du contenu, n'utilisez pas de sélecteurs dépendant du contenu des éléments. Ce sera un cauchemar de maintenance pour chaque lieu. Essayez de parler avec les développeurs et utilisez les techniques qu'ils ont utilisées pour externaliser le texte dans l'application, tels que les dictionnaires, les ensembles de ressources, etc. Voici mon blog qui l'explique en détail.

modifier 1

Grâce à @parishodak, voici le lien link qui fournit les chiffres prouvant que les performances CSS sont meilleures

69
nilesh

Je maintiendrai l'impopulaire sur l'opinion de la balise SO Selenium selon laquelle XPATH est préférable à CSS à plus long terme.

Permettez-moi d’abord de parler de "l’éléphant dans la pièce" - xpath est plus lent que css.

Avec le pouvoir actuel du processeur (à lire: tout ce qui a été produit au cours des 5 dernières années), même sur les ordinateurs virtuels browserstack/saucelabs, et le développement des navigateurs (à lire: tous ceux populaires de ces 5 dernières années), ce n’est guère le cas. Les moteurs de navigateur se sont développés, le support de xpath est uniforme, IE est hors de propos (espérons pour la plupart d'entre nous). Cette comparaison, dans l’autre réponse, est citée un peu partout, mais elle est très contextuelle (combien de personnes courent ou s’inquiètent-elles contre) avec IE8?

S'il y a une différence, c'est en fraction de milliseconde

Pourtant, la plupart des infrastructures de niveau supérieur ajoutent de toute façon au moins 1 ms de temps système par rapport à l’appel brut Selenium (encapsuleurs, gestionnaires, stockage d’état, etc.); mon arme personnelle de choix - robotframework - ajoute au moins 2 ms, ce que je suis plus qu'heureux de sacrifier pour ce qu'elle fournit. Un aller-retour réseau d'un AWS us-east-1 au hub de BrowserStack est généralement de 11 millisecondes

Donc, avec les navigateurs distants, s’il ya une différence entre xpath et css, elle est éclipsée par tout le reste.


Il n’ya pas beaucoup de comparaisons publiques (j’ai vraiment vu celui qui a été cité), alors voici un cas approximatif, factice et simple. La cible - la page de destination de BrowserStack, et son bouton "Inscription"; une capture d'écran du code HTML:

 enter image description here

Voici le code de test (python):

from Selenium import webdriver
import timeit


if __== '__main__':

    xpath_locator = '//div[@class="button-section col-xs-12 row"]'
    css_locator = 'div.button-section.col-xs-12.row'

    repetitions = 1000

    driver = webdriver.Chrome()
    driver.get('https://www.browserstack.com/')

    css_time = timeit.timeit("driver.find_element_by_css_selector(css_locator)", 
                             number=repetitions, globals=globals())
    xpath_time = timeit.timeit('driver.find_element_by_xpath(xpath_locator)', 
                             number=repetitions, globals=globals())

    driver.quit()

    print("css total time {} repeats: {:.2f}s, per find: {:.2f}ms".
          format(repetitions, css_time, (css_time/repetitions)*1000))
    print("xpath total time for {} repeats: {:.2f}s, per find: {:.2f}ms".
          format(repetitions, xpath_time, (xpath_time/repetitions)*1000))

Pour ceux qui ne sont pas familiers avec python - cela ouvre la page et trouve l'élément - d'abord avec le localisateur css, puis avec xpath; les 1000 répétitions, et le temps moyen pour une trouver en millisecondes.

Les localisateurs sont - pour xpath - "un élément div ayant cette valeur de classe exacte quelque part dans le DOM"; le css est similaire - "un élément div avec cette classe, quelque part dans le DOM". Délibérément choisi pour ne pas être sur-accordé; de plus, le sélecteur de classe est cité pour le CSS comme "le deuxième plus rapide après un identifiant".

Environnement - Chrome v66.0.3359.139, chromedriver v2.38, processeur: ULV Core M-5Y10 fonctionnant généralement à 1,5 GHz (oui, un processeur "de traitement de texte", même pas un bête i7 classique).

Voici le résultat:

css temps total 1000 répétitions: 8.84s, par recherche: 8.84ms

temps total xpath pour 1000 répétitions: 8.52s, par recherche: 8.52ms

Évidemment, les minutages par minute sont assez proches; la différence est 0 .32 millisecondes. Ne sautez pas - le xpath est plus rapide - parfois, css.

Essayons avec un autre ensemble de localisateurs, un peu plus compliqué - un attribut ayant une sous-chaîne (approche commune au moins pour moi, aller après la classe d'un élément lorsqu'une partie de celle-ci a une signification fonctionnelle):

xpath_locator = '//div[contains(@class, "button-section")]'
css_locator = 'div[class~=button-section]'

Les deux localisateurs sont encore sémantiquement identiques - "trouver un élément div ayant dans sa classe l'attribut de cette sous-chaîne" . Voici les résultats:

css temps total 1000 répétitions: 8.60s, par recherche: 8.60ms

temps total xpath pour 1000 répétitions: 8.75s, par recherche: 8.75ms

Diff de 0,15 ms. 

Avec un DOM plus complexe, les résultats sont les mêmes. Je n'ai pas d'URL disponible publiquement sous la main pour donner un exemple, mais j'ai revu des résultats similaires pour xpath et css.


En tant qu'exercice, le même test que celui effectué dans le blog lié dans les commentaires/une autre réponse - la page test est public, de même que le code de test .

Ils font plusieurs choses dans le code - cliquer sur une colonne pour la trier, puis obtenir les valeurs et vérifier le tri de l'interface utilisateur est correct. Je vais le couper - récupérez juste les localisateurs, après tout c'est le test racine, non?

Le même code que ci-dessus, avec ces modifications dans:

L'URL est maintenant http://the-internet.herokuapp.com/tables; il y a 2 tests.

Les localisateurs du premier, "Recherche d'éléments par ID et classe", sont les suivants:

css_locator = '#table2 tbody .dues'
xpath_locator = "//table[@id='table2']//tr/td[contains(@class,'dues')]"

Le résultat:

css temps total 1000 répétitions: 8.24s, par recherche: 8.24ms

temps total xpath pour 1000 répétitions: 8.45s, par recherche: 8.45ms

Diff de 0,2 millisecondes.

Les "Trouver des éléments en parcourant":

css_locator = '#table1 tbody tr td:nth-of-type(4)'
xpath_locator = "//table[@id='table1']//tr/td[4]"

Le résultat:

css temps total 1000 répétitions: 9.29s, par recherche: 9.29ms

temps total xpath pour 1000 répétitions: 8.79s, par recherche: 8.79ms

Cette fois, il est de 0,5 ms (en sens inverse, xpath s’est avéré "plus rapide" ici).


Alors, parmi xpath et css, lequel des deux choisir pour la performance? La réponse est simple: choisissez locating by id

En bref, si l'identifiant d'un élément est unique (comme il est supposé être conforme aux spécifications), sa valeur joue un rôle important dans la représentation interne du DOM par le navigateur, et est donc généralement la plus rapide.


Avec la performance hors de l'image, pourquoi je pense que xpath est meilleur? Simple - polyvalence et puissance.

Xpath est un langage développé pour travailler avec des documents XML. en tant que tel, il permet des constructions beaucoup plus puissantes que css.
 


Enfin, encore une fois très subjectif - lequel choisir? IMHO, il n'y a pas de bon ou de mauvais choix - ce sont des solutions différentes au même problème, et tout ce qui est plus approprié pour le travail devrait être choisi. En tant que fan de xpath, je ne crains pas d'utiliser dans mes projets un mélange des deux - diable, parfois il est beaucoup plus rapide de lancer un fichier CSS, si je sais que le travail sera bien fait.

Finally, again very subjective - which one to chose? IMHO, there is no right or wrong choice - they are different solutions to the same problem, and whatever is more suitable for the job should be picked. Being fan of xpath I'm not shy to use in my projects a mix of both - heck, sometimes it is much faster to just throw a css one, if I know it will do the work just fine.

12
Todor Minakov