Was ist der Unterschied zwischen cssSelector und Xpath und was ist in Bezug auf die Leistung für Cross-Browser-Tests besser?


86

Ich arbeite mit dem Selenium WebDriver 2.25.0 an einer mehrsprachigen Webanwendung und teste hauptsächlich den Seiteninhalt (für verschiedene Sprachen wie Arabisch, Englisch, Russisch usw.).

Für meine Anwendung, die je nach Leistung besser ist und sicherstellt, dass sie alle Browser unterstützt (z. B. IE 7,8,9, FF, Chrome usw.).

Vielen Dank im Voraus für Ihre wertvollen Vorschläge.

Antworten:


107

CSS-Selektoren sind weitaus leistungsfähiger als Xpath und in der Selenium-Community gut dokumentiert. Hier sind einige Gründe,

  • Xpath-Engines sind in jedem Browser unterschiedlich und daher inkonsistent
  • IE verfügt nicht über eine native xpath-Engine, daher injiziert Selen eine eigene xpath-Engine, um die Kompatibilität seiner API zu gewährleisten. Daher verlieren wir den Vorteil, native Browserfunktionen zu verwenden, die WebDriver von Natur aus fördert.
  • Xpath neigen dazu, komplex zu werden und daher meiner Meinung nach schwer zu lesen

Es gibt jedoch Situationen, in denen Sie xpath verwenden müssen, z. B. um nach einem übergeordneten Element oder einem Suchelement anhand seines Textes zu suchen (das würde ich später nicht empfehlen).

Sie können Blog von Simon lesen hier . Er empfiehlt auch CSS über Xpath.

Wenn Sie Inhalte testen, verwenden Sie keine Selektoren, die vom Inhalt der Elemente abhängig sind. Das wird ein Alptraum für jedes Gebietsschema. Versuchen Sie, mit Entwicklern zu sprechen, und verwenden Sie Techniken, mit denen sie den Text in der Anwendung ausgelagert haben, z. B. Wörterbücher oder Ressourcenpakete usw. Hier ist mein Blog , in dem dies ausführlich erläutert wird.

bearbeiten 1

Dank @parishodak ist hier der Link, der die Zahlen enthält, die beweisen, dass die CSS-Leistung besser ist


7
CSS-Selektoren erlauben keinen Text. 'enthält' ist in CSS veraltet. Wie ich oben sagte, haben Selektoren unabhängig vom Inhalt. Inhalte können sich außerhalb befinden. Sie können mit Entwicklern sprechen. Sie müssen den Text ausgelagert haben. Meistens haben sie Wörterbücher pro Gebietsschema. Die Schlüssel in den Wörterbüchern sind also identisch, aber die Werte ändern sich je nach Gebietsschema. Mit diesen Dateien können Sie den Inhalt überprüfen. Beachten Sie, dass Sie native Zeichen mit dem Tool nativ2ascii von JDK in ASCII-Zeichen konvertieren müssen. Ich muss einen Blog darüber schreiben. Ich habe viele Gebietsschemas mit dieser Technik getestet.
Nilesh

1
@Chetan चेतन Ich habe meinen Blog-Link in die Antwort eingefügt. Entschuldigung, es hat eine Weile gedauert. Hoffentlich hilft dir das.
Nilesh

8
@Nilesh: Ich stimme deiner Antwort nicht zu. 1.) CSS-Engines unterscheiden sich auch in jedem Browser. Dies ist kein Argument. 3.) Mit etwas Erfahrung ist XPath sehr einfach zu verstehen und bietet mehr Funktionen als CSS. Wenn Sie nach einem sehr verschachtelten Element suchen, sind beide komplex: XPath und CSS. Nach meiner Erfahrung wird jede allgemeine Antwort auf diese Frage falsch sein. Die Entscheidung CSS / XPATH muss individuell getroffen werden. Die ursprüngliche Frage betraf die Leistung. Ihre Antwort besteht hauptsächlich aus Annahmen und persönlichen Meinungen. Ein echter Beweis wäre, die Leistung zu messen und die Ergebnisse hier zu veröffentlichen.
Elmue

2
Ein sehr guter Artikel, der Ihrem ersten Satz widerspricht: "CSS-Selektoren schneiden weitaus besser ab als Xpath". Es ist nicht so einfach, es kann sogar das Gegenteil sein. Und: "IE hat keine native xpath-Engine, daher injiziert Selen eine eigene xpath-Engine, um die Kompatibilität seiner API zu gewährleisten." Hier leidet Selen an einem Konstruktionsfehler. Es wäre sicherlich besser gewesen, die XPath-Engine in C ++ anstelle von Java-Skript zu implementieren. Aber IE ist tot, jetzt kommt Edge. Hinter allen Leistungsfragen darf nicht vergessen werden, dass CSS keine sehr wichtigen Funktionen wie die Suche nach dem Text eines Elements besitzt.
Elmue

2
elementalselenium.com/tips/32-xpath-vs-css bietet Benchmarks, die darauf hindeuten, dass CSS3 nicht mehr wesentlich schneller ist.
mc0e

45

Ich werde die unpopuläre Meinung zu SO-Selen-Tags vertreten, dass XPath auf längere Sicht CSS vorzuziehen ist .

Dieser lange Beitrag besteht aus zwei Abschnitten: Zuerst lege ich einen Beweis für die Rückseite der Serviette vor, dass der Leistungsunterschied zwischen den beiden 0,1 bis 0,3 Millisekunden beträgt (ja, das sind 100 Mikrosekunden ) , und dann teile ich meine Meinung dazu mit XPath ist mächtiger.


Leistungsunterschied

Lassen Sie uns zuerst "den Elefanten im Raum" angehen - dieser xpath ist langsamer als css.

Mit der aktuellen CPU-Leistung (lesen Sie: alles, was x86 seit 2013 produziert) , selbst auf Browserstack- / Saucelabs / aws-VMs, und der Entwicklung der Browser (lesen Sie: alle gängigen in den letzten 5 Jahren) ist dies kaum der Fall. Die Engines des Browsers haben sich entwickelt, die Unterstützung von xpath ist einheitlich, IE ist nicht im Bilde (hoffentlich für die meisten von uns) . Dieser Vergleich in der anderen Antwort wird überall zitiert, ist aber sehr kontextbezogen - wie viele führen die Automatisierung gegen IE8 aus oder kümmern sich darum?

Wenn es einen Unterschied gibt, ist es in einem Bruchteil einer Millisekunde .

Die meisten übergeordneten Frameworks verursachen jedoch ohnehin mindestens 1 ms Overhead gegenüber dem Roh-Selen-Aufruf (Wrapper, Handler, State Storing usw.). Meine persönliche Waffe der Wahl - RobotFramework - fügt mindestens 2 ms hinzu, was ich gerne für das opfere, was sie bietet. Eine Netzwerkrundfahrt von einem AWS us-east-1 zum BrowserStack-Hub dauert normalerweise 11 Millisekunden .

Wenn also bei Remote-Browsern ein Unterschied zwischen xpath und css besteht, wird dieser von allem anderen in Größenordnungen überschattet.


Die Messungen

Es gibt nicht so viele öffentliche Vergleiche (ich habe wirklich nur den zitierten gesehen) , also - hier ist ein grober Einzelfall, Dummy und einfacher.
Es wird ein Element anhand der beiden Strategien X-mal lokalisieren und die durchschnittliche Zeit dafür vergleichen.

Das Ziel - die Zielseite von BrowserStack und die Schaltfläche "Anmelden"; Ein Screenshot des HTML-Codes beim Schreiben dieses Beitrags:

Geben Sie hier die Bildbeschreibung ein

Hier ist der Testcode (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))

Für diejenigen, die nicht mit Python vertraut sind - es öffnet die Seite und findet das Element - zuerst mit dem CSS-Locator, dann mit dem xpath; Die Suchoperation wird 1.000 Mal wiederholt. Die Ausgabe ist die Gesamtzeit in Sekunden für die 1.000 Wiederholungen und die durchschnittliche Zeit für einen Fund in Millisekunden.

Die Locators sind:

  • für xpath - "ein div-Element mit genau diesem Klassenwert irgendwo im DOM";
  • Das CSS ist ähnlich - "ein div-Element mit dieser Klasse, irgendwo im DOM".

Absichtlich gewählt, um nicht überstimmt zu werden; Außerdem wird der Klassenselektor für das CSS als "der zweitschnellste nach einer ID" angegeben.

Die Umgebung - Chrome v66.0.3359.139, chromedriver v2.38, CPU: ULV Core M-5Y10 läuft normalerweise mit 1,5 GHz (ja, eine "Textverarbeitung", nicht einmal ein normales i7-Biest) .

Hier ist die Ausgabe:

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

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

Offensichtlich sind die Zeitpunkte pro Fund ziemlich nahe beieinander. Die Differenz beträgt 0,32 Millisekunden . Springe nicht "der xpath ist schneller" - manchmal ist es, manchmal ist es CSS.


Versuchen wir es mit einem anderen Satz von Locatoren, der etwas komplizierter ist - einem Attribut mit einer Teilzeichenfolge (zumindest für mich ein gängiger Ansatz, der der Klasse eines Elements nachgeht, wenn ein Teil davon eine funktionale Bedeutung hat) :

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

Die beiden Locators sind wieder semantisch gleich - "finde ein div-Element, dessen Klassenzeichenfolge in dieser Klasse liegt".
Hier sind die Ergebnisse:

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

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

Diff von 0,15 ms .


Als Übung - der gleiche Test wie im verlinkten Blog in den Kommentaren / anderen Antworten - ist die Testseite öffentlich, ebenso wie der Testcode .

Sie machen ein paar Dinge im Code - klicken auf eine Spalte, um danach zu sortieren, dann die Werte abzurufen und zu überprüfen, ob die Sortierung der Benutzeroberfläche korrekt ist.
Ich werde es schneiden - besorgen Sie sich doch nur die Locators - das ist der Wurzeltest, oder?

Der gleiche Code wie oben, mit folgenden Änderungen in:

  • Die URL ist jetzt http://the-internet.herokuapp.com/tables; Es gibt 2 Tests.

  • Die Locators für den ersten - "Finden von Elementen nach ID und Klasse" - sind:

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

Und hier ist das Ergebnis:

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

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

Diff von 0,2 Millisekunden.

Die "Elemente durch Überqueren finden":

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

Das Ergebnis:

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

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

Diesmal sind es 0,5 ms (umgekehrt ist xpath hier "schneller" geworden).

Also 5 Jahre später (bessere Browser-Engines) und nur auf die Leistung des Locators fokussiert (keine Aktionen wie Sortieren in der Benutzeroberfläche usw.), dasselbe Testfeld - es gibt praktisch keinen Unterschied zwischen CSS und XPath.


Also, aus xpath und css, welche der beiden für die Leistung wählen? Die Antwort ist einfach - wählen Sie die Suche nach ID .

Kurz gesagt, wenn die ID eines Elements eindeutig ist (wie es den Spezifikationen entsprechen soll), spielt sein Wert eine wichtige Rolle bei der internen Darstellung des DOM durch den Browser und ist daher normalerweise die schnellste.

Es sind jedoch nicht immer eindeutige und konstante (z. B. nicht automatisch generierte) IDs verfügbar. Dies führt uns zu "Warum XPath, wenn es CSS gibt?".


Der XPath-Vorteil

Warum finde ich xpath besser, wenn die Leistung nicht im Bild ist? Einfach - Vielseitigkeit und Kraft.

Xpath ist eine Sprache, die für die Arbeit mit XML-Dokumenten entwickelt wurde. als solches erlaubt es viel leistungsfähigere Konstrukte als CSS.
Zum Beispiel Navigation in alle Richtungen im Baum - finden Sie ein Element, gehen Sie dann zu seinem Großelternteil und suchen Sie nach einem Kind mit bestimmten Eigenschaften.
Es erlaubt eingebettete boolesche Bedingungen - cond1 and not(cond2 or not(cond3 and cond4)); eingebettete Selektoren - "Finden Sie ein Div mit diesen untergeordneten Elementen mit diesen Attributen und navigieren Sie danach".
XPath ermöglicht die Suche basierend auf dem Wert eines Knotens (seinem Text) - obwohl diese Vorgehensweise verpönt ist, ist es besonders in schlecht strukturierten Dokumenten nützlich (keine bestimmten Attribute, auf die man treten kann, wie dynamische IDs und Klassen) Inhalt) .

Das Einsteigen in CSS ist definitiv einfacher - man kann in wenigen Minuten mit dem Schreiben von Selektoren beginnen; Aber nach ein paar Tagen der Nutzung hat die Leistungsfähigkeit und die Möglichkeiten von xpath CSS schnell überwunden.
Und rein subjektiv - ein komplexes CSS ist viel schwerer zu lesen als ein komplexer xpath-Ausdruck.

Outro;)

Zum Schluss nochmal sehr subjektiv - welches soll man wählen?

IMO, es gibt keine richtige oder falsche Wahl - es handelt sich um unterschiedliche Lösungen für dasselbe Problem, und es sollte ausgewählt werden, was für den Job besser geeignet ist.

Als "Fan" von XPath bin ich nicht schüchtern, in meinen Projekten eine Mischung aus beidem zu verwenden - zum Teufel, manchmal ist es viel schneller, nur ein CSS zu werfen, wenn ich weiß, dass es die Arbeit gut macht.


Wie viele Knoten hat die Anmeldeseite? Anmeldeseiten sind normalerweise sehr einfach, deshalb haben Sie vielleicht nur einen kleinen Unterschied gesehen.
Seite

Andere Leistungstests zeigen einen viel größeren Unterschied zwischen verschiedenen Browsern.
Seite

1
Bei Ihrer ersten Frage ist in der Antwort ein Screenshot des DOM enthalten, und die Seite ist online und öffentlich. Für Ihre erste und zweite, wenn Sie die Antwort sorgfältig lesen, habe ich den gleichen Test wie elementalselenium wiederholt, einen der wenigen verfügbaren Vergleiche, der ziemlich oft zitiert wird, mit dem gleichen Ziel und den gleichen Locators wie sie, aber nur mit 5 Jahre neueren Browsern .
Todor Minakov

3
@TodorMinakov GROSSER POST !!! Ich stimme Ihnen zu 100% zu. Ich denke auch, dass die XPath-Syntax (zumindest für mich) natürlicher ist, weil sie etwas ähnelt, das wir alle sehr gut kennen. Und das sind Datei- / Ordnerpfade. Daher denke ich, dass eine Person ohne CSS- oder XPath-Kenntnisse XPath viel einfacher lernen wird. Da der Leistungsunterschied vernachlässigbar ist, sollte die Lernkurve meiner Meinung nach stark berücksichtigt werden.
Hfontanez

1
Vielen Dank, dass Sie @hfontanez; Tolle Analogie zur Dateisystemstruktur, daran habe ich nicht gedacht. Ich muss allerdings ein bisschen anderer Meinung sein, was die Einstiegsfreundlichkeit betrifft - die XPath-Syntax kann zunächst ein wenig einschüchternd sein, außerdem hat sie einige Fallstricke (Index []nach //zum Beispiel) . Aber nach dem ersten Tag des Lernens und der Verwendung überschreitet so ziemlich jeder den Wendepunkt der Lernkurve :) (CSS-Einstieg ist zugegebenermaßen einfacher, IMHO) .
Todor Minakov

13

Die Debatte zwischen cssSelector und XPath würde als eine der subjektivsten Debatten in der Selenium Community bleiben . Was wir bisher bereits wissen, lässt sich wie folgt zusammenfassen:

  • Die Befürworter von cssSelector sagen, dass es besser lesbar und schneller ist (insbesondere, wenn es mit Internet Explorer ausgeführt wird).
  • Während diejenigen, die für XPath sind , für die Fähigkeit werben, die Seite zu durchqueren (während cssSelector dies nicht kann).
  • Das Durchlaufen des DOM in älteren Browsern wie IE8 funktioniert nicht mit cssSelector , ist aber mit XPath in Ordnung .
  • XPath kann das DOM durchlaufen (z. B. von Kind zu Eltern), während cssSelector nur das DOM durchlaufen kann (z. B. von Eltern zu Kind).
  • Es ist jedoch nicht unbedingt eine schlechte Sache, das DOM mit cssSelector in älteren Browsern nicht durchlaufen zu können, da dies eher ein Indikator dafür ist, dass Ihre Seite ein schlechtes Design aufweist und von einem hilfreichen Markup profitieren könnte.
  • Ben Burton erwähnt, dass Sie cssSelector verwenden sollten, da auf diese Weise Anwendungen erstellt werden. Dies erleichtert das Schreiben, Sprechen und Verwalten der Tests.
  • Adam Goucher sagt, dass er einen hybriden Ansatz wählen soll - sich zuerst auf IDs, dann auf cssSelector zu konzentrieren und XPath nur dann zu nutzen , wenn Sie es benötigen (z. B. das DOM hochgehen ), und dass XPath für fortgeschrittene Locators immer leistungsfähiger sein wird.

Dave Haeffner führte einen Test auf einer Seite mit zwei HTML-Datentabellen durch , wobei eine Tabelle ohne hilfreiche Attribute ( ID und Klasse ) und die andere mit diesen geschrieben wurde. Ich habe das Testverfahren und das Ergebnis dieses Experiments in der Diskussion detailliert analysiert. Warum sollte ich jemals cssSelector- Selektoren im Gegensatz zu XPath für automatisierte Tests verwenden? . Während dieses Experiment zeigte, dass jede Locator-Strategie für alle Browser einigermaßen gleichwertig ist, hat es nicht das gesamte Bild für uns angemessen gezeichnet. Dave Haeffner in der anderen Diskussion Css Vs. X-Pfad unter einem Mikroskoperwähnt, in einem End-to-End - Test gab es eine Menge anderer Variablen im Spiel Start Sauce , Browser starten , und Latenz zu und von der zu testenden Anwendung. Die unglückliche Erkenntnis aus diesem Experiment könnte sein, dass ein Fahrer möglicherweise schneller ist als der andere (z. B. IE gegen Firefox ), obwohl dies überhaupt nicht der Fall war. Um einen echten Eindruck von dem Leistungsunterschied zwischen cssSelector und XPath zu bekommenWir mussten tiefer graben. Dazu haben wir alles von einem lokalen Computer aus ausgeführt und dabei ein Leistungsbenchmarking-Dienstprogramm verwendet. Wir haben uns auch auf eine bestimmte Selen-Aktion konzentriert und nicht auf den gesamten Testlauf. Ich habe das spezifische Testverfahren und das Ergebnis dieses Experiments in der Diskussion cssSelector vs XPath für Selen detailliert analysiert . Bei den Tests fehlte jedoch noch ein Aspekt, nämlich eine größere Browserabdeckung (z. B. Internet Explorer 9 und 10) und das Testen anhand einer größeren und tieferen Seite.

Dave Haeffner in einer anderen Diskussion Css Vs. X Path, Under a Microscope (Teil 2) erwähnt, um sicherzustellen, dass die erforderlichen Benchmarks bestmöglich abgedeckt werden, müssen wir ein Beispiel betrachten, das eine große und tiefe Seite demonstriert .


Versuchsaufbau

Um dieses detaillierte Beispiel zu demonstrieren, wurde eine virtuelle Windows XP-Maschine eingerichtet und Ruby (1.9.3) installiert. Alle verfügbaren Browser und die entsprechenden Browsertreiber für Selenium wurden ebenfalls installiert. Für das Benchmarking wurde Rubys Standardbibliothek benchmarkverwendet.


Testcode

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

Ergebnisse

HINWEIS : Die Ausgabe erfolgt in Sekunden. Die Ergebnisse beziehen sich auf die Gesamtlaufzeit von 100 Ausführungen.

In Tabellenform:

css_xpath_under_microscopev2

In Diagrammform:

  • Chrome :

Chart-Chrom

  • Firefox :

Diagramm-Firefox

  • Internet Explorer 8 :

Diagramm-ie8

  • Internet Explorer 9 :

Diagramm-ie9

  • Internet Explorer 10 :

Diagramm-ie10

  • Oper :

Chart-Oper


Analyse der Ergebnisse

  • Chrome und Firefox sind klar auf eine schnellere cssSelector- Leistung abgestimmt .
  • Internet Explorer 8 ist eine Wundertüte mit cssSelector , die nicht funktioniert, eine außer Kontrolle geratene XPath- Durchquerung, die ~ 65 Sekunden dauert, und eine 38-Sekunden-Tabellenüberquerung ohne cssSelector- Ergebnis, mit der sie verglichen werden kann.
  • In IE 9 und 10 ist XPath insgesamt schneller. In Safari ist es ein Fehler, bis auf ein paar langsamere Durchlaufläufe mit XPath . Und in fast allen Browsern ist die mit XPath durchgeführte Durchquerung verschachtelter Geschwister und Tabellenzellen eine teure Operation.
  • Dies sollte nicht so überraschend sein, da die Locators spröde und ineffizient sind und wir sie vermeiden müssen.

Zusammenfassung

  • Insgesamt gibt es zwei Umstände, unter denen XPath deutlich langsamer als cssSelector ist . Sie sind jedoch leicht zu vermeiden.
  • Der Leistungsunterschied ist leicht zugunsten für Nicht-IE-Browser und leicht zugunsten von für IE-Browser.

Wissenswertes

Mit dieser Bibliothek, in der Dave Haeffner den gesamten Code verpackt hat, können Sie das Benchmarking selbst durchführen .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.