Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Why You May Not Need (or Even Want) to Use Page Objects With Your Webdriver Tests

DZone's Guide to

Why You May Not Need (or Even Want) to Use Page Objects With Your Webdriver Tests

Do you really need to incur the overheads of writing and maintaining page objects?

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

 When implementing tests for web applications with a tool like Selenium Webdriver and Cucumber, it is not uncommon to see interactions abstracted away using a page object. Page objects wrap up a number of interactions with a web page using the Webdriver API in methods that can then be exposed with more user (or business) friendly names.

Consider this example, which describes a page object that is used to interact with Google.

@DefaultUrl("http://www.google.com")
public class GooglePage extends PageObject {

    @FindBy(name="q")
    WebElement search;

    public void searchFor(String keywords) {
        search.sendKeys(keywords, Keys.ENTER);
        waitFor(titleContains("Google Search"));
    }
}

The method searchFor() abstracts away the actual elements used and actions taken in order for a search to be performed. This method could then easily be exposed as a Cucumber step like:

And I perform a Google search for “bdd with cucumber”

The benefits of using a page object are that your test scripts can be written using very straight forward plain English steps. Those writing the test scripts need no understanding of the underlying elements that make up a web application, can describe their desired behaviours at a very high level, and don’t need to update tests if the underlying implementation changes.

But there is no magic in page objects. While they may hide the intricacies of interacting with a web application, at some point someone has to code the exact interactions with each element in order to achieve a higher level behaviour. And usually that interaction is implemented in a language like Java.

Implementing any code in a language like Java has costs. At a minimum you need to be able to write and compile the code, and then distribute it along with the accompanying Cucumber feature in order for it to be useful. For seasoned developers, this is no big deal, and if your testing team has the skillset to work with Java, then page objects might be a practical solution for you.

When we were developing Iridium, the costs of maintaining custom Java code for each app just wasn’t an option. Those who were tasked with writing tests couldn’t (or didn’t particularly want to) write Java, and those who could write Java didn’t have time to design and maintain high level abstractions in page objects for each potential interaction with legacy web apps. What we needed was some kind of middle ground.

If you have been reading this article series on Iridium, you will have already seen that it provides a number of steps that allow testers to replicate interactions with web pages through steps that click, populate, select and verify the state of elements within a page. These steps are at a lower level than what you would see exposed by a page object, but through the use of aliases can be used to describe behaviour without necessarily having any particular understanding of how a web app has been implemented.

To demonstrate how Iridium can be used to describe behaviours without the use of custom Java code or page objects, let’s see how an Iridium test could be written against a website mockup.

The image below is what you would expect to come out of a marketing department as it designs a form to create a new appointment, in this case for a hypothetical spa and relaxation company.

Image title

What is important to realize about these mockups is that they already make decisions about the kind of elements that would be used in the final application. In this mockup you can see drop down lists, check boxes, text boxes, buttons, and calendar widgets. These widgets are staples in web development and UI interaction, and mockups for the vast majority of web applications will use these common elements.

From this mockup we can write this Iridium test script:

Feature: Fill In Appointment Form
  Scenario: Massage at 6:00
    Given I set the alias mappings
      | First Name | |
      | Last Name  | |
      | Email Address | |
      | Phone Number | |
      | Service Selection List | |
      | Appointment Date | |
      | Appointment Time List | |
      | Subscribe To Mailing List | |
      | Comments | |
      | Submit Button | |
  And I open the application
  And I populate the element found by alias "First Name" with "John"
  And I populate the element found by alias "Last Name" with "Smith"
  And I populate the element found by alias "Email Address" with "john@example.org"
  And I populate the element found by alias "Phone Number" with "0411111111"
  And I select "Massage" from the drop down list found by alias "Service Selection List"
  And I click the element found by alias "Appointment Date"
  And I select "6:00 PM" from the drop down list found by alias "Appointment Time List"
  And I click the element found by alias "Subscribe To Mailing List"
  And I populate the element found by alias "Comments" with "Can I please get Alice again if she is available?"
  And I click the element found by alias "Submit Button"
  Then I verify that the page contains the text "Your booking was successfully submitted"

Each of these steps is generic, and come included with Iridium. There is no need to write any custom Java code to implement page objects. And while these steps describe the interactions a user would perform in the web page at a reasonably low level, it is no lower than the implied language used in the mockup.

You’ll notice that none of the steps make assumptions about how an element is found on the page. There are no xpaths, css selectors or IDs listed in this script. Instead, the steps defer those details to the aliased values that have been added, but not yet defined, in the first step of “Given I set the alias mappings”. The only thing that the steps assume is that the elements appearing in the mockup will appear on the page, and can be clicked, populated or selected as you would expect from text boxes, check boxes, drop down lists or buttons.

Of course, this test script doesn’t actually do anything. If you tried to run it, Iridium would throw an exception saying that the aliased values are empty.

Image title

So let's see what it takes to turn this script into something that runs and passes. First, we need an actual web application to run the test against. You can see a very rough implementation of the mockup here. Obviously this implementation is not going to win any awards, but it does have all the elements that the user can interact with, and more importantly provides all the elements that our test script needs to complete successfully.

All that the developer needs to do in order to allow this test script to run and pass is populate the aliases.

Feature: Fill In Appointment Form
  Scenario: Massage at 6:00
    Given I set the alias mappings
      | First Name | firstname |
      | Last Name  | lastname |
      | Email Address | email |
      | Phone Number | phone |
      | Service Selection List | servicelist |
      | Appointment Date | calendar-day-2015-09-01 |
      | Appointment Time List | timeList |
      | Subscribe To Mailing List | subscribe |
      | Comments | comments |
      | Submit Button | submit |
    And I open the application
    And I populate the element found by alias "First Name" with "John"
    And I populate the element found by alias "Last Name" with "Smith"
    And I populate the element found by alias "Email Address" with "john@example.org"
    And I populate the element found by alias "Phone Number" with "0411111111"
    And I select "Massage" from the drop down list found by alias "Service Selection List"
    And I click the element found by alias "Appointment Date"
    And I select "6:00 PM" from the drop down list found by alias "Appointment Time List"
    And I click the element found by alias "Subscribe To Mailing List"
    And I populate the element found by alias "Comments" with "Can I please get Alice again if she is available?"
    And I click the element found by alias "Submit Button"
    Then I verify that the page contains the text "Your booking was successfully submitted"

You can actually run this script for yourself. Right click, download and run this Web Start file to launch the test script above against the implementation of the appointment form. You will see the browser being launched, the form filled in, and the test results being displayed.

Image title

While page objects have their place, you may find that abstracting step descriptions beyond the level of detail that you would expect to find in a mockup is unnecessary. If all parties involved in the design of a web application understand common UI elements like text boxes, buttons, drop down lists and checkboxes, then it may well be appropriate, and more convenient, to write acceptance tests that directly reference actions performed on those elements. The use of aliases in Iridium removes the need for testers to know exactly how elements will be referenced in the final application, only that the elements will exist.

When you are designing your testing strategy, be sure to consider all the costs involved in generating page objects. Custom Java code is expensive, and writing tests that reference element interactions directly may allow you to achieve your testing requirements in less time.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
selenium ,page object pattern ,testing

Published at DZone with permission of Matthew Casperson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}