Skip to main content

_ruby

Example

To test the differences between CSS and XPath, we will use two sets of tests. The first set will work with simple attributes like ID and Class, and the other will traverse the DOM top down to work with nested elements.

Ideally, this would be run locally and the speed of each find element action would be measured and compared. But for this we're going to use Sauce Labs and track the total test time for each run. While the prior is more precise, the latter is more accurate since it demonstrates an end-to-end workflow.

NOTE: For a more rigorous benchmark, check out Tip 33 -- CSS vs. XPath, Under a Microscope.

For our example application we will use a page with two HTML data tables. One table is written without helpful attributes, and the other with them. The test code used can be seen here.

Here are the results after running the suite three consecutive times and averaging them (each linkable to a job in Sauce Labs).

Finding Elements By ID and Class

Browser | CSS | XPath
Internet Explorer 8 | 23 seconds | 22 seconds
Chrome 31 | 17 seconds | 16 seconds
Firefox 26 | 22 seconds | 22 seconds
Opera 12 | 17 seconds | 20 seconds
Safari 5 | 18 seconds | 18 seconds

Finding Elements By Traversing

Browser | CSS | XPath
Internet Explorer 8 | not supported | 29 seconds
Chrome 31 | 24 seconds | 26 seconds
Firefox 26 | 27 seconds | 27 seconds
Opera 12 | 25 seconds | 25 seconds
Safari 5 | 23 seconds | 22 seconds

What The Results Tell Us

The results help illustrate and illuminate a couple of things.

For starters there is no dramatic difference in performance between XPath and CSS. This is surprising since it is the main reason cited in favor of CSS. There may be other functionality or page structures that demonstrates this speed gap (e.g. more dense and complex pages), but it's not readily apparent -- and I'm skeptical that it would make a substantial impact (e.g. the order of magnitude difference demonstrated by Santi in a presentation at the SF Selenium Meetup back in 2011).

Traversing the DOM in older browsers like Internet Explorer 8 does not work with CSS but is fine with XPath. And XPath can walk up the DOM (e.g. from child to parent), whereas CSS can only traverse down the DOM (e.g. from parent to child).

Based on the data, XPath looks more favorable than it once was.

Some Additional Food For Thought

Not being able to traverse the DOM with CSS in older browsers isn't necessarily a bad thing. To me, it's more of an indicator that your page has poor design and could benefit from some helpful markup. I outline an approach in a previous tip under the heading "But What About Older Browsers?".

Some other arguments in favor of CSS are that they are more readable, brief, and concise. While I tend to agree, it is a subjective call. Sauce Labs has a good set of examples that demonstrate CSS and XPath side-by-side to accomplish both simple and advanced tasks. It's worth a look for you to determine for yourself.

In Ben Burton's talk (Selenium WebDriver Best Practices) he posits that you should use CSS because that's how applications are built. This makes the tests easier to write, talk about, and have others help maintain. This is also a point that Santi makes in his presentation.

Adam Goucher's advice is to adopt a more hybrid approach -- focusing first on IDs, then CSS, and leveraging XPath only when you need it (e.g. walking up the DOM). He says he does this without hesitation because it's the right tool for the task, and that XPath will always be more powerful for advanced locators.

Summary

So, which do you choose?

It's a tough call to make. Especially now that we're armed with the knowledge that the choice is not as reliant on performance as it once was. But the choice is not as permanent as choosing a programming language, and if you are using helpful abstraction (e.g. Page Objects) then leveraging a hybrid approach is simple to implement.

It's just a matter of finding what works for you and your team and not listening to all the hype.

Good luck and Happy Testing!