Page Objects? Pattern Objects.

Assess. Build. Coach. Deliver.

Page Objects? Pattern Objects.

When people are tasked with writing an automated test for a web application, they’re going to be writing a tool that interacts with the site just like a human user would. Organizing the software in a way that makes sense can be a chore.

When that test clicks buttons for example, it does so by first locating the item (or “element”) on the screen. It does this using a “locator”. There’s something about the element that the software uses to tell which element it’s working on.

There’s a common approach to organizing this code. Each page on the web app gets its own little chunk of code just for holding all the locators. Each of these code chunks is called a Page Object. Thousands of companies use this approach. It does make it easier to organize code.

But when there’s an enormous site to test? Or a huge number of locators per page? That’s where things get sticky. And that’s where we may need to evolve to the next stage of test automation evolution.

First: Page Objects

A Page Object holds all the locators for buttons, text fields, dropdowns, etc. for a given page.

Here’s an example of a data entry form on a site:

advanced-form

Under the hood, the website code would look like this:

example html

If we wrote our automation code to use a Page Object, it might look like this:

class CustomerRecordPage 
{ 
   elements = { 
      "name" => "//input[@id='name']", 
      "email" => "//input[@id='email']", 
      "investment" => "//select[@id='investment']", 
      "dateJoined" => "//input[@id='dateJoined']", 
      "active" => "//input[@id='active']", 
   } 
}

Now for a small example like this one, this is manageable. But this is one part of a larger system being tested. There may be more of these entry forms on the same page, and there may be multiple pages with this same kind of form.

Dozens. Hundreds.

Page Objects are great, but imagine having 50 Page Objects with 50 locators each. That’s 2,500 locators that have to be maintained.

But here’s where Pattern Objects can help.

Now: Pattern Objects

Developers write some complex software. It’s so complex that they don’t want to spend all their time making buttons and text boxes look consistent across the whole site. That’s why they use some standard tools and frameworks to help with that.

The result is, elements across the whole site have a consistent look and feel. We can use that to our advantage.

Instead of writing a custom locator for every element, we create a generic locator that knows how to find element types.

Let’s look at the example from earlier again:

advanced-form

example html

But, notice also that there’s a pattern to the elements:

  • Each element is wrapped in a <div>
  • Each one also has a <label> describing what the field’s for

So instead of a full page object, we could instead build a Pattern Object for holding these patterns, like this:

class PatternObject {
   patterns = {
      "text_field" => "//div/label[text()='@@']/following-sibling::input",
      "select_list" => "//div/label[text()='@@']/following-sibling::select_list"
   }
}

Because we have generic ways to find these elements, we have to replace the “@@” characters with something that helps us find the particular element we want. Here’s some example code for that:

def enter_text(label, text)
   locator = PatternObject::patterns["text_field"].gsub("@@", label)
   $browser.text_field(:xpath => locator).when_present.set(text)
end

The result? You pass in “Email” and “myemail@gmail.com” to enter_text, and you get a locator of //div/label[text()=’myemail@gmail.com’]/following-sibling::input with the text slapped in there.

Cool!

Why Pattern Objects?

While this may seem like a minor change that shaves off a few lines, consider this: earlier when we said there might be 50 pages with 50 elements, we can still use this Pattern Object to interact with those elements.

Because the app will be (hopefully!) consistent everywhere, then all text boxes, dropdowns, buttons, checkboxes and radio buttons should have the same look-and-feel.

So instead of 2,500 locators to handle every element across the site, we need maybe… 5?

I mean I’m kinda biased here but would you rather maintain 2,500 things or 5 things?

Making Automation Simple

If test automation is just as complex as the software it’s testing, the maintenance doubles. And this is what often kills automation efforts at many companies.

When clients bring Arch DevOps in to make their automation better, many times it’s to clean up and refactor their code into something like this.

It saves literally hundreds of hours and greatly decreases the time to get software to market.

Test automation is a challenge. But it’s not impossible. We know some things. This is one example. We’re happy to share more.

Schedule time to talk with us right here.

 

3 Responses

  1. I recall vaguely hearing about something similar from Yandex. is what you describe similar in any way to the HTML-Elements?

    • Had never heard of that, but yes it does look similar. Although this method is instead of page objects, not in addition to, the grouping logic Yandex uses is pretty close.

  2. It sounds good. Thank you for sharing this approach.

Comments are closed.