act:ualise | technology

22 Jan, 2009

Making your Selenium XPath tests more resilient

Posted by: j pimmel In: testing

For the past few years myself and colleagues have used Selenium extensively to test-drive (and continuously test) all the web-apps which we’ve collectively been responsible for. In that time our massed experience meant we got pretty slick at writing these tests. Then when I started on a new project with a new team, I realised those tips/best practices hadn’t been documented and consequently saw developers new to Selenium introducing brittle tests through no fault of their own. 

Here’s a quick rundown of the most useful things we learnt about Selenium Test Xpaths. Please feel free to comment and add your own tips too!

  • Assuming you are following best practices for CSS styling you ought to already be using IDs and CLASS attributes in markup. If not, why not!?
  • Write XPaths which focus on the ‘pivots’ in a deeply nested XPath; where possible use ID and CLASS (and/or other relevant attributes) to filter down to your target element(s).So where previously you might have had:

    xpath=/div[0]/div[3]/div[6]/span[2]

    You could instead use:

    xpath=//div[@class="foo"]//span[@id="pageTitle"]
  • Test that attributes exist or have the right value, rather than testing text content in pages (especially where that content is dynamic)

    So for example, test that button ID x is in page, and click by the xpath of the button ID, rather than using the Selenium IDE recorded click ‘{text button visual name}’ method.

    Another example might be locating that a A HREF link is going to the right place

    Assert

    xpath=//div[@id="profile"]//a[@class="modifyProfile"]/@href

    is ‘/someLink’

  • For links (or src URL locations) employ regex or globs rather than test FQNs

    Assert that

    xpath=//div[@id="profile"]//a[@class="modifyProfile"]/@href

    is ‘glob:*/deepNestedContext/mofiyProfile.action’

  • A corollary from my opening point; make sure all markup is W3C valid. Helps to avoid shooting yourself in the foot using xpaths (ie: duplicate IDs)
  • Employ selenium extensions to compress repetitious, multi step / test activities into a single test action
  • When iterating over listed content, avoid index based xpaths – dynamic changes could cause failures. Try where possible to specify a search form of xpath

    eg: instead of asserting that

    xpath=//div[0]/span[1]/ul/li[3] is 'bob'

    its far less brittle to write

    xpath=//div[@id="mainContent"]//ul[@id="userList"]/li[text() == 'bob']

    In cases where list order is important then using the list index is of value, but often it can cause more trouble than it’s worth to use indexes.

  • Use storeExpression to store and re-use Xpaths which are repeated often in a test (the benefit being when you do have to change the Xpath you change one place not 15)
  • Use the Selenium IDE in record mode more as a guide than as an absolute way to build up tests; IDE xpaths are inflexible and can’t handle changes as well as xpaths defined with resilience in mind
  • Lastly, but not least, remember IE compatibility for your Selenium RC tests

No Responses to "Making your Selenium XPath tests more resilient"

Comment Form

About

act:ualise | technical blog

notes, observations and obssessions on software quality, agile software development, testing and grails


part of the EnergizedWork experiment