Selenium Element Selectors - I thought xPath was s

2019-02-04 20:15发布

问题:

I ran some tests against a public website to see if I could find differences in the performance of a few different Selenium CSS selectors. I ran one hub with five nodes; mac/chrome/local, mac/safari/local, mac/ff/local, win7/ie9/localVM, and win8/ie10,localVM. The tests were all running in parallel, to try to simulate how I usually run them. I was surprised to see that xPath selectors did not turn out to be the devil that I expected. Maybe there is something funky about my tests? Anyone have any insight?

Here is the test code...

    int cycles = 500;
int yVal = 0;

getPage(“http://www.princeton.edu");

/* try an element that does not have an id*/
startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementByCssSelector("a[href='/main/news/events/']").getLocation().y;
print("By CSS: " + elapsedSeconds());

startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementByCssSelector("div[id='events'] a[href='/main/news/events/']").getLocation().y;
print("By CSS using id: " + elapsedSeconds());


startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementByXPath("//a[@href=\'/main/news/events/']").getLocation().y;
print("By xPath: " + elapsedSeconds());

/* try an element with an id */
//by id
startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementById("events").getLocation().y;
print("By Id: " + elapsedSeconds());

//by CSS
startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementByCssSelector("div[id='events']").getLocation().y;
print("By CSS: " + elapsedSeconds());

// an unnecessarily long xPath expression
startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementByXPath("//span[text()='News at Princeton']/ancestor::div[1]/following-sibling::div[1]").getLocation().y;
print("By longer xPath: " + elapsedSeconds());

// somewhat shorter xPath
startStopwatch();
for (int i = 0; i < cycles; i++)
    yVal = driver.findElementByXPath("//span[text()='Featured Events']/ancestor::div[1]").getLocation().y;
print("By shorter xPath: " + elapsedSeconds());

Here are results, showing xPath to hold its own, all times are in seconds for 500 iterations.

Safari was by far the most erratic performer, with times being strangely different for each test run.

princeton.edu is a pretty run-of-the-mill web page, with fairly easy selectors, but seems to suggest that xPath ain't that bad. I found very much the same thing when testing my work site.

Any thoughts on what I may be missing here??

回答1:

People seem to lazily assume Xpath is slow and should be avoided. When I interview people I cringe when they say they avoid Xpath because it is slow and brittle. The speed, as shown here, is no longer a concern, and xpath is only as brittle as the person who wrote it. In the right scenario Xpath is awesome and can actually improve performance as it allows you to perform in one command that may have taken several (e.g find element then iterate through sub elements can be performed in one xpath)

Oh, and dont get me started on people who think there is only one Xpath for an element and that it is found by right clicking in firebug