Test automation fundamentals
User Interface test automation is difficult at the best of times. Your teams need to work hard to keep automation suites running as smoothly as possible. Automation test suites need to focus on long-term maintainability and value since test software should always be treated with the same care and respect that our production code is treated. (Because test software is production software!)
Many teams struggle with getting stable automation suites in place, especially when their system’s user interface (UI) is changing. Frustration ramps up as teams spend more time chasing broken tests, and each change seems to work only for a few cycles. It’s not uncommon for teams to cut back on, or entirely abandon, their UI automation efforts.
This doesn’t have to be the case, though! Careful planning and implementation around element locator strategies can yield incredible results for automation suites. When I work with teams, I initially focus on element locator strategies since it’s the first place tests will fail at, especially when the UI is frequently updating.
In this article I’ll use Selenium WebDriver and Telerik’s Test Studio as examples; however, the concepts I’m discussing are applicable regardless of whether you’re using someone else’s commercial tool or any of the many wonderful open source APIs/drivers available to you.
What’s the Fuss About Locators?
When we browse a web page, our eyes guide us to the areas on the page we need to interact with: headings to read, images to examine, links to click, input fields to enter text in, etc. When a test automation script plays back, the underlying drivers/toolset need some way to find those same elements on the page. Obviously the scripts don’t have eyes, so the toolset needs another way to handle this.
Every web automation toolset, driver, or API uses some form of “locators” which enable the script to find elements on the page. The exact implementation varies from tool to tool, but the general premise is locators allow different approaches to moving across a page’s document object model (DOM).
Understanding how locators work in your application is critical to your team’s long-term success. (And sanity, quite frankly.) Poorly chosen locators directly impact the stability and speed of your automation suites. Selecting bad locators for rows on a grid, for example, will cause your tests to fail if sort order or data differences cause the target row to appear in a different index. Using a locator based on a long, very specific Xpath will cause a failure even if small changes are made to the page’s structure.
Different Types of Locators
How you choose your locators varies on several different factors:
- The platform your system is developed on. Ruby, ASP.NET Webforms, and other platforms each generate subtly different HTML that’s passed to the client.
- The automation toolset you’re working with. Microsoft’s Coded UI, Watir, HP’s QTP, WebDriver, and Telerik’s Test Studio all have varied differences in how they can deal with locators.
- The biggest factor: the people developing your UI. Different teams approach UI development differently, and you’ll need to understand how those styles impact locators.
With that in mind, I’ll use the following page generated from a simple Ruby on Rails application to cover the basics. This page has an extremely clean, simple DOM which makes it easy to start creating some locators. Figure 1 shows both the page and a portion of its DOM.
Locating Elements with XPath
Per the specification on the W3C’s XPath page http://www.w3schools.com/xpath/, “XPath is a language or grammar for addressing parts of an XML document…” XPath enables you to navigate, query, and filter elements on an HTML page. We can use XPath to create a locator that starts from the top of the DOM and dives down to the exact element we’re interested in, an input field for the username in this case.
The resulting XPath expression is this: /html/body/div/div/form/div/input.
A snippet of a WebDriver test using XPath locators might look something like this:
This particular form of an XPath expression isn’t a good one, however. Its extreme precision is actually a significant drag on the team because even the slightest change to the UI will break any tests using this locator. It’s not hard to envision a small UI change to the login modal, implemented via some text in a <div> element:
Now all tests using the logon screen will fail because they’re trying to find an input field under the second <div>--and that element now contains only the new text “Please enter your credentials”.
You’ll have to spend time updating locators for every test that references this element. Extend this out for all tests in your suite, and for every change that impacts the UI. This quickly becomes a significant loss of time when you have other more valuable things to be focusing on for your project. Despite the brittle example shown above, XPath can be extremely useful when employed thoughtfully.
XPath That Isn’t Evil
XPath’s strength comes from its ability to do complex navigation across the page and create complex queries based on parts of the DOM removed from the element you’re looking to locate. If you do this with a bit of care, you can end up with powerful locators that are useful and aren’t brittle.
We can easily craft a locator for the same username input field based on the adjacent label. Doing so gives us a concise, extremely flexible locator that won’t break if other areas of the UI change:
Sometimes you need more complex XPath that lets you traverse significant parts of the page as part of your locator. The XPath below finds a header with specific text, then moves up, then back down the DOM to select a specific button. It’s not very readable; however, it is extraordinarily powerful.
//div[@class="ode-Box-header-caption" and text()="Palette"]/../../../../../../div//td[@class="gwt-StackPanelContent"]//tr//div[text()="Button"]'
XPath also gives you the ability to examine text inside elements, transform letter cases, and a number of other powerful capabilities. XPath is a tremendous tool in your locator toolbelt when it’s used carefully and wisely.