Qual è la differenza tra cssSelector e Xpath e quale è migliore rispetto alle prestazioni per i test cross browser?


89

Sto lavorando con Selenium WebDriver 2.25.0 su un'applicazione web multilingue e provo principalmente il contenuto della pagina (per lingue diverse come arabo, inglese, russo e così via).

Per la mia applicazione che è migliore in base alle prestazioni e assicurati che dovrebbe essere il supporto per tutti i browser (ad esempio IE 7,8,9, FF, Chrome ecc.).

Grazie in anticipo per i tuoi preziosi suggerimenti.

Risposte:


108

I selettori CSS funzionano molto meglio di Xpath ed è ben documentato nella comunità Selenium. Ecco alcuni motivi,

  • I motori Xpath sono diversi in ogni browser, quindi li rendono incoerenti
  • IE non ha un motore xpath nativo, quindi il selenio inietta il proprio motore xpath per la compatibilità della sua API. Quindi perdiamo il vantaggio di utilizzare le funzionalità del browser native che WebDriver promuove intrinsecamente.
  • Xpath tende a diventare complesso e quindi a renderlo difficile da leggere secondo me

Tuttavia, ci sono alcune situazioni in cui è necessario utilizzare xpath, ad esempio, cercando un elemento genitore o cercando un elemento in base al suo testo (non consiglierei il successivo).

Puoi leggere il blog di Simon qui . Raccomanda anche CSS su Xpath.

Se stai testando il contenuto, non utilizzare selettori che dipendono dal contenuto degli elementi. Sarà un incubo di manutenzione per ogni locale. Prova a parlare con gli sviluppatori e usa le tecniche che hanno usato per esternare il testo nell'applicazione, come dizionari o bundle di risorse ecc. Ecco il mio blog che lo spiega in dettaglio.

modifica 1

Grazie a @parishodak, ecco il link che fornisce i numeri che dimostrano che le prestazioni CSS sono migliori


7
I selettori CSS non consentono il testo. "contiene" è deprecato in CSS. Come ho detto sopra, disponi di selettori indipendenti dal contenuto. Il contenuto può risiedere all'esterno. Puoi parlare con gli sviluppatori. Devono aver esternalizzato il testo. La maggior parte delle volte hanno dizionari per locale. Quindi le chiavi nei dizionari sono le stesse ma i valori cambiano in base alle impostazioni locali. È possibile utilizzare questi file per convalidare il contenuto. Nota che devi convertire i caratteri nativi in ​​caratteri ASCII usando lo strumento nativ2ascii da JDK. Devo scrivere un blog su questo. Ho testato molti locali usando questa tecnica.
nilesh

1
@Chetan चेतन Ho aggiunto il mio link al blog nella risposta. Scusa, ci è voluto un po '. Spero che questo ti possa aiutare.
nilesh

8
@ Nilesh: non sono d'accordo con la tua risposta. 1.) Anche i motori CSS sono diversi in ogni browser. Questo non è un argomento. 3.) Con una certa esperienza XPath è molto facile da capire e offre più funzionalità rispetto ai CSS. Se cerchi un elemento molto annidato, sono entrambi complessi: XPath e CSS. Nella mia esperienza qualsiasi risposta generale a questa domanda sarà sbagliata. La decisione CSS / XPATH deve essere presa individualmente. La domanda iniziale riguardava le prestazioni. La tua risposta consiste principalmente in supposizioni e opinioni personali. Una vera prova sarebbe MISURARE le prestazioni e pubblicare i risultati qui.
Elmue

2
Un ottimo articolo che contraddice la tua prima frase: "I selettori CSS funzionano molto meglio di Xpath". Non è così semplice, potrebbe anche essere il contrario. E: "IE non ha un motore xpath nativo, quindi il selenio inietta il proprio motore xpath per compatibilità con la sua API." Qui il selenio soffre di un errore di progettazione. Sarebbe stato sicuramente meglio implementare il motore XPath in C ++ invece che in java script. Ma IE è morto, ora arriva Edge. Dietro tutte le domande sulle prestazioni non bisogna dimenticare che i CSS mancano di funzionalità molto importanti come la ricerca del testo di un elemento.
Elmue

2
elementalselenium.com/tips/32-xpath-vs-css fornisce benchmark che suggeriscono che css3 non è più significativamente più veloce.
mc0e

46

Terrò l'impopolare opinione sui tag di selenio SO che XPath è preferibile ai CSS nel lungo periodo.

Questo lungo post ha due sezioni: prima metto una prova sul retro del tovagliolo, la differenza di prestazioni tra i due è di 0,1-0,3 millisecondi (sì, sono 100 micro secondi) , e poi condividerò la mia opinione sul perché XPath è più potente.


Differenza di prestazioni

Per prima cosa affrontiamo "l'elefante nella stanza": xpath è più lento di css.

Con l'attuale potenza della cpu (leggi: qualsiasi cosa x86 prodotta dal 2013) , anche su VM browserstack / saucelabs / aws, e lo sviluppo dei browser (leggi: tutti quelli popolari negli ultimi 5 anni) non è certo il caso. I motori del browser si sono sviluppati, il supporto di xpath è uniforme, IE è fuori dai giochi (si spera per la maggior parte di noi) . Questo confronto nell'altra risposta viene citato ovunque, ma è molto contestuale: quanti sono in esecuzione o si preoccupano per l'automazione contro IE8?

Se c'è una differenza, è in un file frazione di millisecondo .

Tuttavia, la maggior parte dei framework di livello superiore aggiunge comunque almeno 1 ms di overhead sulla chiamata al selenio grezzo (wrapper, gestori, memorizzazione dello stato ecc.); la mia arma preferita - RobotFramework - aggiunge almeno 2 ms, che sono più che felice di sacrificare per ciò che fornisce. Un viaggio di andata e ritorno di rete da un AWS us-east-1 all'hub di BrowserStack è in genere di 11 millisecondi .

Quindi con i browser remoti se c'è una differenza tra xpath e css, viene messa in ombra da tutto il resto, in ordini di grandezza.


Le misurazioni

Non ci sono molti confronti pubblici (in realtà ho visto solo quello citato) , quindi eccone un caso singolo approssimativo, fittizio e semplice.
Individuerà un elemento in base alle due strategie X volte e confronterà il tempo medio per quello.

Il target: la pagina di destinazione di BrowserStack e il relativo pulsante "Registrati"; uno screenshot dell'html mentre scriveva questo post:

inserisci qui la descrizione dell'immagine

Ecco il codice di 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))

Per chi non ha familiarità con Python - apre la pagina e trova l'elemento - prima con il css locator, poi con xpath; l'operazione di ricerca viene ripetuta 1.000 volte. L'output è il tempo totale in secondi per le 1.000 ripetizioni e il tempo medio per una ricerca in millisecondi.

I localizzatori sono:

  • per xpath - "un elemento div avente questo valore di classe esatto, da qualche parte nel DOM";
  • il css è simile: "un elemento div con questa classe, da qualche parte nel DOM".

Scelto deliberatamente per non essere troppo sintonizzato; inoltre, il selettore di classe è citato per il css come "il secondo più veloce dopo un id".

L'ambiente - Chrome v66.0.3359.139, chromedriver v2.38, cpu: ULV Core M-5Y10 normalmente in esecuzione a 1,5 GHz (sì, un "word-processing", nemmeno un normale i7 beast) .

Ecco l'output:

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

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

Ovviamente i tempi per ritrovamento sono piuttosto vicini; la differenza è di 0,32 millisecondi . Non saltare "xpath è più veloce" - a volte lo è, a volte è css.


Proviamo con un altro set di locatori, un po 'più complicato - un attributo con una sottostringa (approccio comune almeno per me, che segue la classe di un elemento quando una parte di essa ha un significato funzionale) :

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

I due locatori sono di nuovo semanticamente uguali - "trova un elemento div che ha nel suo attributo di classe questa sottostringa".
Ecco i risultati:

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

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

Diff di 0,15 ms .


Come esercizio - lo stesso test eseguito nel blog collegato nei commenti / altra risposta - la pagina di test è pubblica, così come il codice di test .

Stanno facendo un paio di cose nel codice: fare clic su una colonna per ordinare in base ad essa, quindi ottenere i valori e controllare che l'ordinamento dell'interfaccia utente sia corretto.
Lo taglierò - prendi solo i localizzatori, dopotutto - questo è il test di root, giusto?

Lo stesso codice di cui sopra, con queste modifiche in:

  • L'URL è adesso http://the-internet.herokuapp.com/tables; ci sono 2 test.

  • I localizzatori per il primo - "Ricerca di elementi per ID e classe" - sono:

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

Ed ecco il risultato:

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

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

Diff di 0,2 millisecondi.

Il "Trovare elementi attraversando":

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

Il risultato:

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

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

Questa volta è di 0,5 ms (al contrario, xpath è risultato "più veloce" qui).

Quindi 5 anni dopo (motori di browser migliori) e concentrandosi solo sulle prestazioni dei localizzatori (nessuna azione come l'ordinamento nell'interfaccia utente, ecc.), Lo stesso banco di prova: non c'è praticamente alcuna differenza tra CSS e XPath.


Quindi, al di fuori di xpath e css, quale dei due scegliere per le prestazioni? La risposta è semplice: scegli la localizzazione per id .

Per farla breve, se l'id di un elemento è unico (come dovrebbe essere secondo le specifiche), il suo valore gioca un ruolo importante nella rappresentazione interna del DOM del browser, e quindi di solito è il più veloce.

Tuttavia, gli ID univoci e costanti (ad esempio non generati automaticamente) non sono sempre disponibili, il che ci porta a "perché XPath se c'è CSS?"


Il vantaggio di XPath

Con le prestazioni fuori dall'immagine, perché penso che xpath sia migliore? Semplice: versatilità e potenza.

Xpath è un linguaggio sviluppato per lavorare con documenti XML; in quanto tale, consente costrutti molto più potenti di css.
Ad esempio, la navigazione in ogni direzione dell'albero: trova un elemento, quindi vai dai suoi nonni e cerca un suo figlio con determinate proprietà.
Consente condizioni booleane incorporate - cond1 and not(cond2 or not(cond3 and cond4)); selettori incorporati - "trova un div che ha questi figli con questi attributi, e poi naviga in base ad esso".
XPath consente la ricerca in base al valore di un nodo (il suo testo) - per quanto questa pratica sia disapprovata, è utile soprattutto nei documenti strutturati male (nessun attributo definito su cui calpestare, come ID dinamici e classi - individua l'elemento in base al suo testo contenuto) .

Il passaggio in CSS è decisamente più semplice: si può iniziare a scrivere selettori in pochi minuti; ma dopo un paio di giorni di utilizzo, la potenza e le possibilità di xpath superano rapidamente css.
E puramente soggettivo: un CSS complesso è molto più difficile da leggere di un'espressione xpath complessa.

Outro;)

Infine, ancora una volta molto soggettivo: quale scegliere?

IMO, non esiste una scelta giusta o sbagliata: sono soluzioni diverse allo stesso problema e dovrebbe essere scelta qualsiasi cosa sia più adatta per il lavoro.

Essendo "un fan" di XPath non sono timido nell'usare nei miei progetti un mix di entrambi - diamine, a volte è molto più veloce lanciarne uno CSS, se so che funzionerà bene.


Quanti nodi hanno la pagina di accesso? Le pagine di accesso sono generalmente molto semplici, ecco perché potresti aver notato solo una piccola differenza.
pagep

Altri test delle prestazioni mostrano differenze molto maggiori tra i diversi browser.
pagep

1
Per la tua prima domanda: uno screenshot del DOM è presente nella risposta e la pagina è online e pubblica. Per il tuo primo e secondo, se leggi attentamente la risposta, ho ripetuto lo stesso test di elementalselenium, uno dei pochi confronti disponibili che viene spesso citato, utilizzando lo stesso target e gli stessi localizzatori, ma solo con 5 anni di browser più recenti .
Todor Minakov

3
@TodorMinakov GRANDE POST !!! Sono d'accordo con te al 100% Penso anche che la sintassi XPath sia anche più naturale (almeno per me) perché assomiglia a qualcosa che tutti conosciamo molto bene. E questo è il percorso di file / cartelle. Quindi penso che una persona con zero conoscenza di CSS o XPath, imparerà XPath molto più facilmente. Poiché la differenza di prestazioni è trascurabile, penso che la curva di apprendimento meriti una forte considerazione.
hfontanez

1
Grazie @hfontanez; grande analogia con la struttura del file system, non ci ho pensato. Tuttavia, devo essere un po 'in disaccordo per la facilità di passaggio: la sintassi XPath può essere un po' intimidatoria all'inizio, inoltre ha alcuni gotcha-s (indice []dopo //per esempio) . Ma dopo il giorno iniziale di apprendimento e utilizzo, praticamente tutti attraversano il punto di svolta della curva di apprendimento :) (il passaggio di CSS è ammettibilmente più facile, IMHO) .
Todor Minakov

13

Il dibattito tra cssSelector vs XPath rimarrebbe come uno dei dibattiti più soggettivi nella comunità Selenium . Ciò che già sappiamo finora può essere riassunto come:

  • Le persone a favore di cssSelector dicono che è più leggibile e più veloce (specialmente se eseguito su Internet Explorer).
  • Mentre quelli a favore di XPath sostengono la sua capacità di attraversare la pagina (mentre cssSelector non può).
  • Attraversare il DOM in browser meno recenti come IE8 non funziona con cssSelector ma va bene con XPath .
  • XPath può risalire il DOM (ad es. Da figlio a genitore), mentre cssSelector può solo attraversare il DOM (ad es. Da genitore a figlio)
  • Tuttavia, non essere in grado di attraversare il DOM con cssSelector nei browser meno recenti non è necessariamente una cosa negativa in quanto è più un indicatore che la tua pagina ha un design scadente e potrebbe trarre vantaggio da qualche utile markup.
  • Ben Burton afferma che dovresti usare cssSelector perché è così che vengono create le applicazioni. Ciò rende i test più facili da scrivere, di cui parlare e che altri aiutano a mantenerli.
  • Adam Goucher afferma di adottare un approccio più ibrido, concentrandosi prima sugli ID, poi su cssSelector e sfruttando XPath solo quando ne hai bisogno (ad esempio, salendo sul DOM) e che XPath sarà sempre più potente per i localizzatori avanzati.

Dave Haeffner ha eseguito un test su una pagina con due tabelle di dati HTML , una tabella è scritta senza attributi utili ( ID e Classe ) e l'altra con loro. Ho analizzato in dettaglio la procedura di test e il risultato di questo esperimento nella discussione Perché dovrei usare i selettori cssSelector invece di XPath per i test automatici? . Sebbene questo esperimento abbia dimostrato che ogni strategia di localizzazione è ragionevolmente equivalente su tutti i browser, non ha dipinto adeguatamente l'intero quadro per noi. Dave Haeffner nell'altra discussione Css Vs. X Path, al microscopiomenzionato, in un test end-to-end c'erano molte altre variabili in gioco l' avvio di Sauce , l' avvio del browser e la latenza da e verso l'applicazione sotto test. La sfortunata conclusione di quell'esperimento potrebbe essere che un driver potrebbe essere più veloce dell'altro (ad esempio IE vs Firefox ), quando in realtà non era affatto così. Per avere un vero assaggio di quale sia la differenza di prestazioni tra cssSelector e XPath, dovevamo scavare più a fondo. Lo abbiamo fatto eseguendo tutto da una macchina locale utilizzando un'utilità di benchmarking delle prestazioni. Ci siamo anche concentrati su un'azione specifica del selenio piuttosto che sull'intero test e abbiamo eseguito le cose numerose volte. Ho analizzato la procedura di test specifica e il risultato di questo esperimento in dettaglio nella discussionecssSelector vs XPath per il selenio . Ma ai test mancava ancora un aspetto, ovvero una maggiore copertura del browser (ad esempio, Internet Explorer 9 e 10) e il test su una pagina più grande e più profonda.

Dave Haeffner in un'altra discussione Css vs. Menziona X Path, Under a Microscope (Parte 2) , per assicurarci che i benchmark richiesti siano coperti nel miglior modo possibile, dobbiamo considerare un esempio che dimostri una pagina ampia e profonda .


Configurazione di prova

Per dimostrare questo esempio dettagliato, è stata configurata una macchina virtuale Windows XP ed è stato installato Ruby (1.9.3) . Sono stati installati anche tutti i browser disponibili e i relativi driver browser equivalenti per Selenium. Per il benchmarking, è benchmarkstata utilizzata la libreria standard di Ruby .


Codice di prova

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

Risultati

NOTA : l'output è in secondi ei risultati si riferiscono al tempo di esecuzione totale di 100 esecuzioni.

In forma di tabella:

css_xpath_under_microscopev2

In formato grafico:

  • Chrome :

cromo-grafico

  • Firefox :

grafico-firefox

  • Internet Explorer 8 :

chart-ie8

  • Internet Explorer 9 :

chart-ie9

  • Internet Explorer 10 :

chart-ie10

  • Opera :

opera-grafico


Analizzando i risultati

  • Chrome e Firefox sono chiaramente ottimizzati per prestazioni cssSelector più veloci .
  • Internet Explorer 8 è un pacchetto di cssSelector che non funziona, un traversal XPath fuori controllo che richiede circa 65 secondi e un attraversamento di una tabella di 38 secondi senza risultato cssSelector con cui confrontarlo.
  • In IE 9 e 10, XPath è complessivamente più veloce. In Safari, è un problema, ad eccezione di un paio di corse di attraversamento più lente con XPath . E in quasi tutti i browser, l'attraversamento di fratelli nidificati e l'attraversamento di celle di tabella eseguiti con XPath sono un'operazione costosa.
  • Questi non dovrebbero essere così sorprendenti poiché i localizzatori sono fragili e inefficienti e dobbiamo evitarli.

Sommario

  • In generale, ci sono due circostanze in cui XPath è notevolmente più lento di cssSelector . Ma sono facilmente evitabili.
  • La differenza di prestazioni è leggermente a favore di per i browser non IE e leggermente a favore di per i browser IE.

Curiosità

Puoi eseguire il benchmarking da solo, utilizzando questa libreria in cui Dave Haeffner ha racchiuso tutto il codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.