Writing automated tests is more than just a luxury for any agile software development team. It is a need, and is an essential tool to find bugs quickly during early phases of software development cycles. Although writing automated tests may seem like an easy task for engineers, there is still the possibility of ending up with poorly implemented tests, and the high cost of code maintenance in any agile process. ROI, Maintenance & Re-usability is on the high priority in every Feasibility study of Automation. In this article, we will take a look at one such maintenance problem and how to overcome it using the much-famous Page Object Model. Nowadays, the page object model is a new Test automation buzz word 🙂 being asked during Testing Job interviews as well.
Writing Basic Automation Scripts | The Problem
Starting a UI Automation project is not difficult. For those who may be unfamiliar – Pick a tool, select the programming language and start scripting the functional flows. How? Simple, script will login to the application, navigate to the required page, find elements/objects on that page, perform actions and then verify/assert the results. 10 Test cases = these steps replicated 10 times. Simple, right? Yeah! Writing scripts is not tough. What’s tough in automation is maintaining those scripts 😉 Scripts won’t stop at the count of 10. As the requirements grow, functional flows to-be-automated increase – the automation test suite will involve more & more lines of code & test scripts.
With any interface, and I suppose web interfaces in particular, it is common that both minor and major changes to the UI is implemented frequently. This could be a new design, restructuring of fields and buttons, and this will likely impact your test. Suddenly the properties of ‘Username’ textbox changes in one of the release. Now what? Yeah! Update the locator/properties in all the scripts that use the ‘Username’ textbox. One time, that’s okay. What if in a release properties/locators of few of the objects/elements changes? Yeah, a little frustrating to update these in each & every script that uses these. What if the project maintains different Test suites – Smoke Tests, Sanity Tests, Regression-1, Functional-1, and Regression-2? Nah! This is not done. It is far more frustrating to update the same ‘small’ little thing in all the scripts every time. There has to be a better way to do it. That’s when you think of a better approach to maintainable Automation.
The concept of ‘Object Repository’
‘Repository’ is a generic term meaning a central location in which data is stored and managed. And why would someone need a central location? To access data from a single source of truth, which can be accessed across-locations by multiple users. Now apply the same concept to Automation.
Say you want to test multiple application flows wherein some objects/elements are referenced in each flow. What does your logic say? Yeah! To have a central location of these objects/elements & access it for different flows. Now what should this repository contain w.r.t. Automation Testing? Yeah, as you would have guessed – Objects’ properties to identify it or Element locators to identify them, and common methods that can operate on these objects/locators.
Coming back to our ‘maintenance’ problem – how does this Object repository solves the purpose? It’s simple. There is a central object repository where all object properties or element locators are stored. And every script access this central location to identify the elements & act on it. Now if few objects/elements are changed during development, we just need to update it in this central repository – in turn used by all the test scripts. Sounds logical? Yes, it is!
This is one of the reason why we need an automation framework. Apart from these basic concepts, framework acts as a foundation or an infrastructure on top of which we can build test scripts that are easy to maintain, execute & report. To know more about what are the benefits organizations tend to achieve using frameworks – please visit our earlier post here.
Implementing Object Repository
Now that we know the problem and the solution, the next obvious step is to learn how to implement the same. Few automation tools like HPE UFT have an inbuilt support for Object repositories, i.e. they already have the mechanism in place. You just need to add objects in the repository and start using them in the scripts. For other tools like Selenium Webdriver, we need to explicitly find a way to create and organize object repository. That’s where Design Patterns come into picture.
What’s a Design Pattern?
The most challenging part in test automation has always been the code maintenance. A lot of test automation projects have drowned or were scrapped due to the inability of the frameworks to cope up with the growing code-bases. A Design pattern is a generic solution to a common software design/architecture problem. Implementation of these design patterns leads to inclusion of best practices and best solution, evolved over time by others while working with similar problems. Design patters has very clear goals: describe common solutions for common problems, create shared language for community, and improve understanding & reuse of existing approaches. Design patterns show how to design test automation so that it will be efficient and easy to maintain.
There are easy to understand & adopt design patterns that can significantly improve readability and maintainability of the test automation code. For e.g. Page Object Model, Façade Pattern, Factory Pattern, Singleton pattern, Strategy Design Pattern, etc.
Page Object Model | A Design Pattern
“If you have WebDriver APIs in your test methods, You’re Doing It Wrong”.
Page Object Model is a Design pattern to create Object Repository for web UI elements, i.e. writing all the functionalities/reusable components of a page that we want to automate in a separate class. As the name suggests – ‘Model’ application Web ‘Pages’ as ‘Objects’. Web pages are represented as classes, and the various elements (locators) on the page are defined as variables on the class. All possible user interactions can then be implemented as methods on the class.
“Within your web app’s UI there are areas that your tests interact with. A Page Object simply models these as objects within the test code. This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place.”
It essentially models the pages/screen of the application as objects called Page Objects, all the functions that can be performed in the specific page are encapsulated in the page object of that screen. The responsibility of every Page Object is to wrap HTML elements and encapsulate interactions with the UI, meaning that this is where all calls to WebDriver will go. This is where most Web Elements are. And this is the only place you need to modify when the UI changes.
Note: Page Object Model is a Design Pattern, not an Automation Framework. Page Object Model (POM) can be used in any kind of automation framework. For different types of Automation Frameworks, please refer our earlier post here. Some testers also use ‘properties file’ in Selenium Automation Framework to form Object repository.
Advantages of Page Object Model
- Page Object Pattern enables clear separation between operations & flows in the UI and the verification, i.e. separation between the Test code (actual test scripts) and Page specific code (locators/methods). This concept makes code cleaner and easy to understand.
- Code Maintenance: Code changes only on Page Object Classes when a UI change occurs. It enhances test maintenance.
- Code Re-usability: write once, use multiple times within different test scripts.
- Since the repository is separated from test scripts, we can use the same repository for a different purpose with different tools. For example, integrate POM with TestNG/JUnit for functional Testing and at the same time with JBehave/Cucumber for acceptance testing.
- Code becomes less and optimized because of the reusable page methods in the POM classes.
- Methods get more realistic names which can be easily mapped with the operation happening in UI.
- Readability: Improves readability due to clean separation between test code and page specific code.
- And finally, this is good and solid Object oriented design.
How to implement Page Object Model
An implementation of the page object model can be achieved by separating the abstraction of the test object and the test scripts.
- Create a new Package file that will contain all the Page Object classes, i.e. classes for each web page of the application. Create different packages for Page Objects, Utilities, Test Data, Test Scripts and Modular actions. It is always recommended to use this structure, as it is easy to understand, easy to use and easy to maintain.
- Create new class files within above package corresponding to every web page within an application. For example, LoginPage, HomePage, SearchResults, ProductDetail, etc.
- This Page Object class files will contain the elements locator and methods to act upon these elements. The methods defined in the Page Object classes can then be re-used in test scripts wherever it is applicable. Thus reducing the redundant code and ease maintainability.
- Identify the locators and define them on the top of the class. In this way we can achieve readability of test scripts and we can easily identify locators and change them if needed at only one place.
- We need to identify and list of all the possible functionalities on a web page and then write methods in such a way that they are re-used.
- For a method where User is navigating to any other web page, return that page object. Else return the current page object.
- A page object should represent meaningful elements of a page and not necessarily a complete page. For example, Header-Content-Footer can be modeled as three Page Objects instead of one.
Think twice, Code once
Page Object Model has now a days become very popular in the industry and many companies are using it because of its easy test maintenance and reduction of duplicate code. The main advantage of Page Object Model is that if the UI changes for any page, it doesn’t require us to change any tests, we just need to change only the code within the Page Objects (only at one place). We encourage the reader to search the internet for other blogs on this subject. Many have written on this design pattern and can provide useful tips.
Page Object Model make it easy to model web pages and make the life of QAs much simpler. When done right, these Page Object classes can be reused across your entire test suite. By abstracting away User interactions in your Page Object Model and keeping your test routines light and simple, you can adapt your test suite to changing requirements with little effort. So whether you are just getting started with Selenium or you are managing a large suite of Selenium regression tests, you will most likely benefit from introducing the Page Object Model into you code. Think twice, Code once!