Simplifying UI Testing with Page Object Model and Controllers

Saira Mughal
motive-eng
Published in
6 min readOct 8, 2020

Before we begin:

KeepTruckin is on a mission to connect the world’s trucks. With the leading ELD and fleet management platform, we are bringing the trucking industry online and fundamentally changing the way freight is moved on our roads.

Adding new features and support before the world imagines them is one of the core characteristics at KeepTruckin. As time passes, more features and enhancements are added; each addition makes the experience that much better.

Reaching our customers with a rich-featured but reliable product is a challenge that our teams are working on globally. Quality assurance is one of the main aspects before pushing anything to production. Ensuring quality through manual means can be time-consuming and is subject to human error. To speed up the process, automation testing is being exercised.

The key challenge while writing automation scripts is to design an architecture that is scalable and error-free, just like the company’s product. In this article, we will discuss the architecture and customized pattern, which was derived after thoughtful research and study.

The information available in this blog is helpful for readers who are interested to learn about:

  • Design patterns for test automation.
  • Implementation of automation tests for web-based applications.

In automation testing, writing test scripts is easy. But, writing scalable, reliable, and speedy tests are very challenging. The Internet is flooded with coding guidelines and design patterns to design and implement tests efficiently. One of the most popular design patterns being used is the Page Object Model.

What is POM?

As the name suggests, a Page Object Model comprises objects, each representing a page interface in the application under test. In the programming world, an object is an instance of a class, which contains data members and some actions to be performed on those data members. An object in POM is no different. Data members of a Page Object are merely elements present on the page such as a button or a label, while member functions are the actions that these elements can perform such as click or getText, etc.

Collection of multiple Page Objects makes a single repository for the services or operations offered by the application rather than having these services scattered throughout the tests. This approach isolates the Tests layer from Page Object, so any change in the UI requires updating the relevant Page Object class only.

KeepTruckin is growing significantly, and to support our customers’ needs, the KeepTruckin web application is also getting enriched with many salient features. This increases the need to expand automation test coverage at a fast pace. Initially, we started writing our automation tests using POM, but eventually, we were forced to think for some innovation because of the following problems with typical POM pattern:

Problems with POMS:

1: Test scalability:

Generally, a test consists of expected user actions, TestData, and assertions. In the traditional POM model, supplying Data to Page Object’s methods, executing flows, and verifying expectations are all included in the spec files — making the spec files extremely thick. Any change or addition will cost significant time and effort.

2: Code redundancy:

There are cases when some specific set of steps are repeatedly executed. Adding those tests to the Page Object file means polluting the OOP architecture. But if these steps are added to a spec file, then we need to add the same steps in multiple scenarios. This will result in code redundancy which contradicts the claimed OOP’s basic advantages.

3: Difficult to maintain:

There can be a condition when some flows are stretched across the components. In traditional POMs, an automation engineer will have to add another Page Object file to access their methods. Consequently, as the app grows, too many components in a single file may result in significant code maintenance.

Solve all the problems by introducing an intermediate layer, i.e. Controllers:

After dealing with all the above-mentioned issues and immense brainstorming, the Page Object Model with Controller solution was conceived. Adding a controller layer simplifies the roles and responsibilities of specs and Page Object. To follow this pattern, Page Objects are designed purely on the bases of OOP’s basic principle i.e. abstraction and encapsulation. UI elements in the Page Objects are private and can be accessed only through Get/Set methods defined for them. Whereas a spec file just triggers the flow which needs to be verified. Finally, the Controller layer consists of all methods or flows which input the test data to Page Objects and are responsible for asserting the results.

Below is a detailed explanation of how the above-mentioned issues are addressed by the controller:

1: Tests are scalable:

Introducing controllers specs files are clean and precise. Similarly, Page Objects are responsible for UI elements interaction only. Controllers will perform the interactions required by Specs with POMs along with any logical operations required. So any addition or update is very easy and convenient. The test writer just needs to update the appropriate layers only.

2: Reduce Code Redundancy:

If a set of steps is required to verify a particular scenario multiple times in a spec, then simply include the required controller to the calling spec/controller file and execute the flow as many times as you want. That particular part of code is written only once in any controller and eliminates the repetitive code.

3: Easy to Maintain:

When a QA engineer wants to verify a scenario across multiple UI components, then controllers can play a vital role in maintaining the codebase. Simply include a particular controller to any other controller or spec file, and verify the relevant functionality. As every controller is responsible for its scoped functionality, maintaining the codebase does not become hectic or time taking.

To sum up…

In the end, we can summarize that adding a controller layer is just like “Divide and conquer.” Test scripts are divided into three layers: specs, controller, and Page Objects. Page Objects are only responsible for UI elements interaction. Controllers manage all the interactions between specs and Page Objects by defining flows and verifying assertions. Specs files are light and easy to understand and simply call the required user flow from the controller. With the introduction of this architecture, we also observed that any new SDET or even manual QA resource can simply understand the architecture and make modifications if required.

From our author…

I would like to thank my mentor Ali Asim and my teammate Rabia Altaf for all their help and guidance to write and implement this idea. This turned out to be an excellent design pattern for test automation scripts!

I feel fortunate to be a part of KeepTruckin, where everyone is welcome to talk about what’s on their mind and get full support to implement. Leaders train, develop, and promote employees from within and maintain the best talent. It is one of the secrets to KeepTruckin’s fast-paced progress. This company is producing incredible tech leaders for the industry and I am glad to be a part of the team.

We’re excited to be a part of the Medium community! We plan to post many new stories, so be sure to follow our publication. Want to join the growing team at KeepTruckin? We’re hiring!

--

--