How to Implement POM Design Pattern with Selenium
In this article, we'll discuss the advantages of using the Page Object Model (POM) for automated testing with Selenium, Java, and JUnit 5. First, we'll explain what POM is and then try writing tests without it. During this process, we'll note any difficulties we face. After that, we'll tackle these issues by applying POM principles to our code. This approach will show how POM improves the reusability, readability, and maintenance of tests.
Introduction:
The Page Object Model (POM) is a popular approach used in test automation to improve how we manage code and ensure stable testing. By organizing web page elements and their actions into reusable parts, POM helps us avoid repeating code and keeps our test scripts clear and easy to manage.
Why Use POM?
Enhanced Code Reusability: Page objects can be reused in different tests, which means less repetition and more efficient testing.
Improved Test Readability and Maintainability: POM organizes page details into easy-to-understand components. This makes test scripts shorter, clearer, and easier to manage over time.
Reduced Code Duplication: POM helps to avoid repeating the same code for finding and interacting with web elements. This leads to cleaner, more efficient code.
Simplified Maintenance: When the user interface (UI) changes, updates only need to be made in the page objects. This makes it faster and easier to keep test scripts up-to-date.
Test Cases Overview:
Here are the test cases we'll be working with:
Implementing Without POM:
First, we'll create a class called TestBase to establish a common setup and teardown for our tests. This class is like the base of our testing setup, making sure everything works the same way every time we run a test.
Next, we'll create a test class called LoginTests. This class contains two test methods for verifying the login functionality.
Challenges and Issues:
The issue with navigating link to the login page:
Moving the repeated code on lines 6 and 16, to the
setUp()
method initially appears as a solution but becomes cumbersome if other tests navigate to different pagesCreating a
navigateToLoginPage()
method inLoginTests
helps reduce code repetition. However, if other test classes need this method, it breaks the DRY (Don't Repeat Yourself) principle, leading to more work in maintaining the code.
A better solution is to use the Page Object Model (POM) design pattern. This involves creating a method called navigateToLoginPage()
in the LoginPage
class. This makes it easier to navigate between pages.
Here's how we can navigate to the login page using POM:
new LoginPage(driver).navigateToLoginPage();
or
LoginPage loginPage = new LoginPage(driver);
loginPage.navigateToLoginPage();
This approach helps in reducing code duplication and ensures easier maintenance. If there's a need to change the link, we only need to modify it in ONE PLACE.
Issue with duplicate other elements:
Also, these elements are duplicated:
driver.findElement(By.name("username")).sendKeys("Admin");
driver.findElement(By.name("password")).sendKeys("admin123");
driver.findElement(By.tagName("button")).click();
Additionally, duplicating these elements increases the maintenance overhead. Any changes to the login process, such as updating element locators, would need to be applied in multiple locations, increasing the risk of errors and making the code harder to maintain.
Imagine if you have multiple test classes that require login functionality. With the current approach of duplicating login-related elements and actions in each test method, any change or update to the login process would necessitate modifying code in multiple places. This not only increases the likelihood of errors but also makes maintenance tasks cumbersome and time-consuming.
Implementing with POM:
If we separate each page along with its elements, methods, and actions into corresponding classes (Page Objects), we can reap several benefits:
Using the Page Object Model (POM) design pattern to structure our automation framework offers us the opportunity to build more reliable, maintainable, and efficient automated tests.
This approach allows us to encapsulate the functionality and behavior of each page within dedicated classes, improving code organization and enhancing test maintainability. Additionally, it promotes code reuse by providing a centralized location for interacting with page elements, leading to more efficient test development and easier maintenance.
Steps to implement POM:
1- Project Structure Setup: Begin by organizing your project structure. Create a directory named "pages" within the "src/main/java/"
2- Page Object Creation: within the "pages" directory, create a new Java class named "LoginPage.java" to represent the login page. This class will encapsulate all interactions with the login page elements.
In this step, we create the initial LoginPage class with the necessary fields for locating elements on the login page and add the navigateToLoginPage() method. This method navigates the WebDriver instance to the login page URL.
In this step, we will add methods to the LoginPage class for interacting with the login page elements such as entering the username, password, and clicking the login button.
loginValidUser(): Enters valid username and password, clicks the login button, and returns a DashboardPage object.
loginInvalidUser(): Enters invalid username and password, clicks the login button.
getInvalidMessage(): Retrieves the text of the invalid credentials message.
Let's refactor login methods to avoid duplication and improve code readability
Finally, let's optimize our tests by refactoring the test methods in the LoginTests class to utilize the refactored login methods from the LoginPage page object.
Resources:
Page Object Models: Explore the Selenium documentation for best practices and guidelines on implementing the Page Object Model (POM).
GitHub Repository: Access the base code for the project discussed in this article.
Conclusion:
In conclusion, adopting the Page Object Model (POM) in our test automation framework brings numerous benefits. From enhanced code reusability to simplified maintenance, POM helps streamline our testing process and ensures stable, maintainable automation.
In the next article, we'll delve into Fluent-POM, a design pattern aimed at streamlining test automation and enhancing code readability.
Subscribe to my newsletter
Read articles from Hassan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by