Quelle est la différence entre cssSelector et Xpath et quel est le meilleur en termes de performances pour les tests multi-navigateurs?


88

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

Pour mon application qui est meilleure en fonction des performances et assurez-vous qu'elle doit être compatible avec tous les navigateurs (ie IE 7,8,9, FF, Chrome, etc.).

Merci d'avance pour vos précieuses suggestions.

Réponses:


107

Les sélecteurs CSS fonctionnent bien mieux que Xpath et il 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 n'a pas de moteur xpath natif, donc le sélénium injecte son propre moteur xpath pour la compatibilité de son API. Par conséquent, nous perdons l'avantage d'utiliser des fonctionnalités de navigateur natives que WebDriver promeut par nature.
  • Xpath a tendance à devenir complexe et donc difficile à lire à mon avis

Cependant, dans certaines situations, vous devez utiliser xpath, par exemple, rechercher un élément parent ou rechercher un élément par son texte (je ne recommanderais pas ce dernier).

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 qui dépendent du contenu des éléments. Ce sera un cauchemar de maintenance pour chaque région. Essayez de parler avec les développeurs et utilisez des techniques qu'ils ont utilisées pour externaliser le texte dans l'application, comme des dictionnaires ou des ensembles de ressources, etc. Voici mon blog qui l'explique en détail.

modifier 1

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


7
Les sélecteurs CSS n'autorisent pas le texte. 'contient' est obsolète en CSS. Comme je l'ai dit ci-dessus, ayez des sélecteurs indépendants du contenu. Le contenu peut résider à l'extérieur. Vous pouvez parler aux développeurs. Ils doivent avoir externalisé le texte. Ils ont la plupart du temps des dictionnaires par langue. Ainsi, les clés dans les dictionnaires sont les mêmes mais les valeurs changent selon les paramètres régionaux. Vous pouvez utiliser ces fichiers pour valider le contenu. Notez que vous devez convertir les caractères natifs en caractères ascii à l'aide de l'outil nativ2ascii de JDK. Je dois écrire un blog à ce sujet. J'ai testé de nombreux paramètres régionaux en utilisant cette technique.
nilesh

1
@Chetan चेतन J'ai ajouté mon lien de blog dans la réponse. Désolé, cela a pris du temps. J'espère que cela vous aidera.
nilesh

8
@Nilesh: Je ne suis pas d'accord avec votre réponse. 1.) Les moteurs CSS sont également différents dans chaque navigateur. Ce n'est pas un argument. 3.) Avec une certaine expérience, XPath est très facile à comprendre et offre plus de fonctionnalités que CSS. Si vous recherchez un élément très imbriqué, ils sont tous deux complexes: XPath et CSS. D'après mon expérience, toute réponse générale à cette question sera erronée. La décision CSS / XPATH doit être prise individuellement. La question initiale concernait la performance. Votre réponse se compose principalement d'hypothèses et d'opinions personnelles. Une vraie preuve serait de MESURER la performance et d'afficher les résultats ici.
Elmue

2
Un très bon article qui contredit votre première phrase: "Les sélecteurs CSS fonctionnent bien mieux que Xpath". Ce n'est pas si simple, c'est peut-être même le contraire. Et: "IE n'a pas de moteur xpath natif, donc le sélénium injecte son propre moteur xpath pour la compatibilité de son API." Ici, Selenium souffre d'une erreur de conception. Il aurait sûrement été préférable d'implémenter le moteur XPath en C ++ au lieu du script java. Mais IE est mort, vient maintenant Edge. Derrière toutes les questions de performance, il ne faut pas oublier que CSS manque de fonctionnalités très importantes comme la recherche du texte d'un élément.
Elmue

2
elementalselenium.com/tips/32-xpath-vs-css fournit des repères qui suggèrent que css3 n'est plus beaucoup plus rapide.
mc0e du

46

Je vais tenir l'opinion impopulaire sur la balise SO sélénium selon laquelle XPath est préférable à CSS à long terme.

Ce long article comporte deux sections - d'abord, je vais mettre une preuve à l'arrière de la serviette, la différence de performance entre les deux est de 0,1 à 0,3 millisecondes (oui; c'est 100 microsecondes ) , puis je partagerai mon opinion pourquoi XPath est plus puissant.


Différence de performance

Commençons par aborder "l'éléphant dans la pièce" - ce xpath est plus lent que le CSS.

Avec la puissance actuelle du processeur (lire: tout ce qui a été produit par x86 depuis 2013) , même sur les VM Browserstack / saucelabs / aws, et le développement des navigateurs (lire: tous les plus populaires au cours des 5 dernières années), ce n'est guère le cas. Les moteurs du navigateur se sont développés, le support de xpath est uniforme, IE est hors de propos (espérons-le pour la plupart d'entre nous) . Cette comparaison dans l'autre réponse est citée partout, mais elle est très contextuelle - combien exécutent - ou se soucient - de l'automatisation par rapport à IE8?

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

Pourtant, la plupart des frameworks de niveau supérieur ajoutent au moins 1 ms de surcharge par rapport à l'appel de sélénium brut de toute façon (wrappers, gestionnaires, stockage d'état, etc.); mon arme personnelle de choix - RobotFramework - ajoute au moins 2 ms, que je suis plus qu'heureux de sacrifier pour ce qu'elle fournit. Un aller-retour réseau entre un AWS us-east-1 et le hub de BrowserStack dure généralement 11 millisecondes .

Donc, avec les navigateurs distants, s'il y a une différence entre xpath et css, elle est éclipsée par tout le reste, par ordre de grandeur.


Les mesures

Il n'y a pas beaucoup de comparaisons publiques (je n'ai vraiment vu que celle citée) , donc - voici un cas unique, factice et simple.
Il localisera un élément par les deux stratégies X fois et comparera le temps moyen pour cela.

La cible - la page de destination de BrowserStack, et son bouton «Inscription»; une capture d'écran du html en écrivant ce post:

entrez la description de l'image ici

Voici le code de test (python):

from selenium import webdriver
import timeit


if __name__ == '__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 - il ouvre la page et trouve l'élément - d'abord avec le localisateur css, puis avec le xpath; l'opération de recherche est répétée 1 000 fois. La sortie est le temps total en secondes pour les 1 000 répétitions et le temps moyen pour une découverte 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".

Choisi délibérément pour ne pas être sur-accordé; aussi, le sélecteur de classe est cité pour le css comme "le deuxième plus rapide après un identifiant".

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

Voici le résultat:

css total time 1000 repeats: 8.84s, per find: 8.84ms

xpath total time for 1000 repeats: 8.52s, per find: 8.52ms

De toute évidence, les délais de recherche sont assez proches; la différence est de 0,32 millisecondes . Ne sautez pas "le xpath est plus rapide" - parfois c'est le cas, parfois c'est css.


Essayons avec un autre ensemble de localisateurs, un tout petit 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 quand une partie de celui-ci a une signification fonctionnelle) :

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

Les deux localisateurs sont à nouveau sémantiquement les mêmes - "trouver un élément div ayant dans son attribut de classe cette sous-chaîne".
Voici les résultats:

css total time 1000 repeats: 8.60s, per find: 8.60ms

xpath total time for 1000 repeats: 8.75s, per find: 8.75ms

Diff de 0,15 ms .


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

Ils font quelques choses dans le code - en cliquant sur une colonne pour trier par elle, puis en obtenant les valeurs et en vérifiant que le tri de l'interface utilisateur est correct.
Je vais le couper - il suffit de récupérer 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 par classe" - sont:

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

Et voici le résultat:

css total time 1000 repeats: 8.24s, per find: 8.24ms

xpath total time for 1000 repeats: 8.45s, per find: 8.45ms

Diff de 0,2 millisecondes.

"Recherche d'é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 total time 1000 repeats: 9.29s, per find: 9.29ms

xpath total time for 1000 repeats: 8.79s, per find: 8.79ms

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

Donc 5 ans plus tard (meilleurs moteurs de navigateurs) et en se concentrant uniquement sur les performances des localisateurs (pas d'actions comme le tri dans l'interface utilisateur, etc.), le même banc d'essai - il n'y a pratiquement aucune différence entre CSS et XPath.


Alors, hors xpath et css, lequel des deux choisir pour les performances? La réponse est simple: choisissez la localisation par identifiant .

Pour faire court, si l'id d'un élément est unique (comme il est supposé l'être selon les spécifications), sa valeur joue un rôle important dans la représentation interne du navigateur du DOM, et est donc généralement la plus rapide.

Pourtant, les identifiants uniques et constants (par exemple non générés automatiquement) ne sont pas toujours disponibles, ce qui nous amène à "pourquoi XPath s'il y a du CSS?"


L'avantage XPath

Avec les performances hors de l'image, pourquoi est-ce que 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.
Par exemple, la navigation dans toutes les directions de l'arborescence - trouvez un élément, puis allez chez ses grands-parents et recherchez un enfant de celui-ci ayant certaines propriétés.
Il permet des conditions booléennes intégrées - cond1 and not(cond2 or not(cond3 and cond4)); sélecteurs intégrés - "trouver un div ayant ces enfants avec ces attributs, puis naviguer en fonction de celui-ci".
XPath permet une recherche basée sur la valeur d'un nœud (son texte) - aussi désapprouvée que cette pratique soit, elle est utile en particulier dans les documents mal structurés (pas d'attributs définis sur lesquels marcher, comme les identifiants et les classes dynamiques - localisez l'élément par son texte contenu) .

Le pas dans le CSS est certainement plus facile - on peut commencer à écrire des sélecteurs en quelques minutes; mais après quelques jours d'utilisation, la puissance et les possibilités de xpath ont rapidement dépassé le css.
Et purement subjectif - un CSS complexe est beaucoup plus difficile à lire qu'une expression xpath complexe.

Outro;)

Enfin, encore une fois très subjectif - lequel choisir?

OMI, il n'y a pas de bon ou de mauvais choix - ce sont des solutions différentes au même problème, et ce qui convient le mieux au travail doit être choisi.

Étant "fan" de XPath, je ne suis pas gêné d'utiliser dans mes projets un mélange des deux - diable, parfois il est beaucoup plus rapide d'en lancer un CSS, si je sais que cela fera très bien le travail.


Combien de nœuds ont la page de connexion? Les pages de connexion sont généralement très simples, c'est pourquoi vous n'avez peut-être vu que peu de différence.
pagep

D'autres tests de performances montrent une différence beaucoup plus grande entre les différents navigateurs.
pagep

1
Pour votre première question - une capture d'écran du DOM est présente dans la réponse, et la page est en ligne et publique. Pour votre premier et votre deuxième, si vous lisez attentivement la réponse, j'ai répété le même test que elementalselenium, l'une des rares comparaisons disponibles qui est assez souvent citée, en utilisant la même cible et les mêmes localisateurs qu'eux, mais avec seulement 5 ans de navigateurs plus récents .
Todor Minakov

3
@TodorMinakov GRAND POSTE !!! Je suis d'accord avec vous à 100% Je pense aussi que la syntaxe XPath est aussi plus naturelle (du moins pour moi) car elle ressemble à quelque chose que nous connaissons tous très bien. Et ce sont les chemins de fichiers / dossiers. Je pense donc qu'une personne n'ayant aucune connaissance de CSS ou XPath, apprendra XPath beaucoup plus facilement. Étant donné que la différence de performance est négligeable, je pense que la courbe d'apprentissage mérite une attention particulière.
hfontanez

1
Merci @hfontanez; grande analogie avec la structure du système de fichiers, je n'y ai pas pensé. Je dois cependant être un peu en désaccord pour la facilité d’intervention - la syntaxe XPath peut être un peu intimidante au début, en plus elle a quelques pièges (index []après //par exemple) . Mais après le premier jour d'apprentissage et d'utilisation, à peu près tout le monde franchit le point de basculement de la courbe d'apprentissage :) (l'étape css est admirablement plus facile, à mon humble avis) .
Todor Minakov

13

Le débat entre cssSelector et XPath resterait l'un des débats les plus subjectifs de la communauté Selenium . Ce que nous savons déjà jusqu'à présent peut se résumer comme suit:

  • Les gens en faveur de cssSelector disent qu'il est plus lisible et plus rapide (surtout lorsqu'il est exécuté avec Internet Explorer).
  • Alors que ceux en faveur de XPath vantent sa capacité à traverser la page (alors que cssSelector ne le peut pas).
  • Traverser le DOM dans des navigateurs plus anciens comme IE8 ne fonctionne pas avec cssSelector mais convient parfaitement avec XPath .
  • XPath peut remonter le DOM (par exemple de l'enfant au parent), alors que cssSelector ne peut parcourir que le DOM (par exemple du parent à l'enfant)
  • Cependant, ne pas pouvoir parcourir le DOM avec cssSelector dans les navigateurs plus anciens n'est pas nécessairement une mauvaise chose car c'est plus un indicateur que votre page a une mauvaise conception et pourrait bénéficier d'un balisage utile.
  • Ben Burton mentionne que vous devriez utiliser cssSelector car c'est ainsi que les applications sont construites. Cela rend les tests plus faciles à rédiger, à discuter et à faire en sorte que d'autres aident à maintenir.
  • Adam Goucher dit d'adopter une approche plus hybride - en se concentrant d'abord sur les identifiants, puis sur cssSelector , et en exploitant XPath uniquement lorsque vous en avez besoin (par exemple en remontant le DOM) et que XPath sera toujours plus puissant pour les localisateurs avancés.

Dave Haeffner a effectué un test sur une page avec deux tableaux de données HTML , un tableau est écrit sans attributs utiles ( ID et Classe ), et l'autre avec eux. J'ai analysé la procédure de test et le résultat de cette expérience en détail dans la discussion Pourquoi devrais-je utiliser les sélecteurs cssSelector par opposition à XPath pour les tests automatisés? . Bien que cette expérience ait démontré que chaque stratégie de localisation est raisonnablement équivalente sur tous les navigateurs, elle ne nous a pas suffisamment brossé le tableau. Dave Haeffner dans l'autre discussion Css Vs. Chemin X, sous un microscopementionné, il y avait beaucoup d'autres variables en jeu dans un un test de bout en bout démarrage de la sauce , le navigateur de démarrage et temps d' attente vers et depuis l'application en cours de test. Le résultat malheureux de cette expérience pourrait être qu'un pilote peut être plus rapide que l'autre (par exemple IE vs Firefox ), alors qu'en fait, ce n'est pas du tout le cas. Pour avoir un aperçu de la différence de performances entre cssSelector et XPath, nous devions creuser plus profondément. Nous l'avons fait en exécutant tout à partir d'une machine locale tout en utilisant un utilitaire d'analyse comparative des performances. Nous nous sommes également concentrés sur une action Selenium spécifique plutôt que sur l'ensemble du test, et avons exécuté les choses plusieurs fois. J'ai analysé en détail la procédure de test spécifique et le résultat de cette expérience dans la discussion cssSelector vs XPath pour le sélénium . Mais les tests manquaient encore un aspect, à savoir une plus grande couverture du navigateur (par exemple, Internet Explorer 9 et 10) et des tests sur une page plus grande et plus profonde.

Dave Haeffner dans une autre discussion Css Vs. X Path, Under a Microscope (Part 2) mentionne, afin de s'assurer que les repères requis sont couverts de la meilleure façon possible, nous devons considérer un exemple qui démontre une page grande et profonde .


Test SetUp

Pour illustrer cet exemple détaillé, une machine virtuelle Windows XP a été configurée et Ruby (1.9.3) a été installé. Tous les navigateurs disponibles et leurs pilotes de navigateur équivalents pour Selenium ont également été installés. Pour l'analyse comparative, la bibliothèque standard de Ruby a benchmarkété utilisée.


Code de test

require_relative 'base'
require 'benchmark'

class LargeDOM < Base

  LOCATORS = {
    nested_sibling_traversal: {
      css: "div#siblings > div:nth-of-type(1) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3)",
      xpath: "//div[@id='siblings']/div[1]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]"
    },
    nested_sibling_traversal_by_class: {
      css: "div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1",
      xpath: "//div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]"
    },
    table_header_id_and_class: {
      css: "table#large-table thead .column-50",
      xpath: "//table[@id='large-table']//thead//*[@class='column-50']"
    },
    table_header_id_class_and_direct_desc: {
      css: "table#large-table > thead .column-50",
      xpath: "//table[@id='large-table']/thead//*[@class='column-50']"
    },
    table_header_traversing: {
      css: "table#large-table thead tr th:nth-of-type(50)",
      xpath: "//table[@id='large-table']//thead//tr//th[50]"
    },
    table_header_traversing_and_direct_desc: {
      css: "table#large-table > thead > tr > th:nth-of-type(50)",
      xpath: "//table[@id='large-table']/thead/tr/th[50]"
    },
    table_cell_id_and_class: {
      css: "table#large-table tbody .column-50",
      xpath: "//table[@id='large-table']//tbody//*[@class='column-50']"
    },
    table_cell_id_class_and_direct_desc: {
      css: "table#large-table > tbody .column-50",
      xpath: "//table[@id='large-table']/tbody//*[@class='column-50']"
    },
    table_cell_traversing: {
      css: "table#large-table tbody tr td:nth-of-type(50)",
      xpath: "//table[@id='large-table']//tbody//tr//td[50]"
    },
    table_cell_traversing_and_direct_desc: {
      css: "table#large-table > tbody > tr > td:nth-of-type(50)",
      xpath: "//table[@id='large-table']/tbody/tr/td[50]"
    }
  }

  attr_reader :driver

  def initialize(driver)
    @driver = driver
    visit '/large'
    is_displayed?(id: 'siblings')
    super
  end

  # The benchmarking approach was borrowed from
  # http://rubylearning.com/blog/2013/06/19/how-do-i-benchmark-ruby-code/
  def benchmark
    Benchmark.bmbm(27) do |bm|
      LOCATORS.each do |example, data|
    data.each do |strategy, locator|
      bm.report(example.to_s + " using " + strategy.to_s) do
        begin
          ENV['iterations'].to_i.times do |count|
         find(strategy => locator)
          end
        rescue Selenium::WebDriver::Error::NoSuchElementError => error
          puts "( 0.0 )"
        end
      end
    end
      end
    end
  end

end

Résultats

REMARQUE : la sortie est en secondes et les résultats correspondent au temps d'exécution total de 100 exécutions.

Sous forme de tableau:

css_xpath_under_microscopev2

Sous forme de graphique:

  • Chrome :

graphique-chrome

  • Firefox :

graphique-firefox

  • Internet Explorer 8 :

graphique-ie8

  • Internet Explorer 9 :

chart-ie9

  • Internet Explorer 10 :

chart-ie10

  • Opéra :

carte-opéra


Analyse des résultats

  • Chrome et Firefox sont clairement réglés pour des performances cssSelector plus rapides .
  • Internet Explorer 8 est un sac à main de cssSelector qui ne fonctionnera pas, une traversée XPath incontrôlable qui prend ~ 65 secondes et une traversée de table de 38 secondes sans résultat cssSelector pour la comparer.
  • Dans IE 9 et 10, XPath est globalement plus rapide. Dans Safari, c'est un tirage au sort, à l'exception de quelques exécutions de traversée plus lentes avec XPath . Et dans presque tous les navigateurs, la traversée des frères imbriqués et la traversée des cellules de table effectuées avec XPath sont une opération coûteuse.
  • Celles-ci ne devraient pas être si surprenantes car les localisateurs sont fragiles et inefficaces et nous devons les éviter.

Sommaire

  • Dans l'ensemble, il existe deux circonstances où XPath est nettement plus lent que cssSelector . Mais ils sont facilement évitables.
  • La différence de performance est légèrement en faveur de pour les navigateurs non-IE et légèrement en faveur de pour les navigateurs IE.

Trivia

Vous pouvez effectuer le benchmarking vous-même, en utilisant cette bibliothèqueDave Haeffner a enveloppé tout le code.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.