Simple is Usually Better

June 26, 2014 Stephen Atkinson

Accessors and Page Objects in Automated Testing

There are many ways to formulate an automated test for a specific page layout. One such way is to use vaguely constructed, yet universal methods to interact with elements and objects on the page.  For example, say you want to have a universal click command for buttons:

browser.button(:identifier_type, ‘unique_id’).click

This definitely has its benefits, as you can use it on any button that is currently displayed in the page layout.  The difficulty lies when the page layout is changed and that identifier is modified, which is often the case in a fast moving agile environment. Not only that, but sometimes dynamically generated elements are difficult to address since the dynamic nature of the element can many times go against the nature of a unique_id.

One such solution to this problem is by looking at each unique page as its own object.  Take a look at this simple, crude example page layout:

 

unique_id
 

 

To access the ‘Login’ button:

browser.button(:id, ‘Login’).click

Same for Password and Email:

browser.text_field(:id, ‘Email’).set(‘My Value’)

But what if beyond the accessor unique ID (text, id) changing, what if the actual element type itself changed? What if Login was no longer a button and was now a link? Your universal click link would no longer work for this button.

A common and elegant solution to this problem is to create a page object for Example_Home_Page.html. Each element contained within this page has its own set of methods (accessors, getters, setters) contained with in the Example_Home_Page.object. This solution allows you to quickly and easily find and modify or update tests for a specific page.

The designer who decided to change my Login button to a Login link wouldn’t pose as much of a problem, as the solution is simple:

class Example_Home_Page

  def login_to_app(email, password)

    browser.text_field(:id, ‘Email’).set(email)

    browser.text_field(:id, ‘Email’).set(password)

    #browser.button(:id, ‘Login’).click #THE OLD ACCESSOR

    browser.link(:id, ‘Login’).click

  end

end

           
In this class, you can easily add, remove and modify methods for each element of the page in a very readable format. Next, let’s see how it’s easier to deal with the dynamic content. Lots of times, dynamic content can be the most difficult content in which to construct test coverage. This is especially true when there is a disconnect between the designer/developer and automation engineer. A common (and easy example for this…example) way to do this is using xpath. Let’s construct a simple Cucumber test:

Scenario: I want to get the headlines of the newest item in the news feed.

            When I get the newest headline of the newest item in the news feed

            Then I successfully get the newest item in the news feed

Now, let’s modify our Example_Home_Page object to house our new method:

class Example_Home_Page

  def login_to_app(email, password)

    browser.text_field(:id, ‘Email’).set(email)

    browser.text_field(:id, ‘Email’).set(password)

    #browser.button(:id, ‘Login’).click

    browser.link(:id, ‘Login’).click

  end

  def get_newest_headline

    browser.span(:xpath, ‘//@example/xpath/to/headline/element’).when_present.text

  end

end

This new method, get_newest_headline, will always check the top element which just happens to ALWAYS have this xpath address.  Because of that, you don’t have to worry about unique IDs that must remain the same (minus the xpath, which allows the content to be dynamic). Additionally, if the xpath changes in design, just simply change it in your page object.

To summarize, there are a number of solutions in which to interact with elements on a page and many of these solutions can be tailored to fit any project.  In my case and experience, it has always been easier to keep your tests organized as page objects so that maintaining them is as simple as possible.  And simple is usually better. 

About the Author

Stephen Atkinson

Stephen Atkinson, Distil's QA Automation Engineer, started his software engineering career as a developer for the East Carolina University, where he took part in research and development of video games that would be used in a medical environment for diagnosis and rehabilitation. From there, he expanded his knowledge into automated software testing at iContact and later, 6fusion.

More Content by Stephen Atkinson
Previous Article
Distil Networks: One to Watch
Distil Networks: One to Watch

Network World has released its 10 Security Start-ups to Watch report. Distil Networks was chosen because of...

Next Article
Hats, Prevention, and Your Business
Hats, Prevention, and Your Business

It’s important to think of Distil as a part of your infrastructure. The customers that take ownership and d...