Wednesday, September 4, 2013

Page Object Pattern - What and Why?

Today I will be writing about Page Objet pattern which became famous when details about it was mentioned in the selenium wiki.

Page Object pattern solves one of the biggest problem that any automation framework face i.e Managing utils, managing methods, reducing code duplicity etc. It solves this by suggesting certain methodology for managing and modelling the code.

Some of the main points that it suggests are:
1. Model your application UI pages as classes in your framework. (There is no hard-and-fast rule that the whole page on the UI should be represented by one class, you can also create classes for the sections of the page if they are used in other UI pages or sections.)
2. Each class will contain methods that perform the actual functionality provided on the page or section that the said class represents.
3. Each method in the Page class should return the object of the same page class or another page class if the said method/functionality navigate the UI to a new page.
4. Method names inside the page class should represent the actual functionality that it performs.

Let’s take this by an example:
We’ll take the same example as mentioned in the Selenium wiki, you have a login page where user enters username and password. If the login is successful user will get navigated to the home page else an error will be thrown on the UI.

Now converting this use case to a Page Object pattern we’ll have two classes LoginPage and HomePage defined. LoginPage will contains functions related to entering username, entering password, login using a given username and password, clicking on submit button etc. HomePage will contain functionality related to the HomePage, in this case we will have the functionality to verify the HomePage. Below is a class representation of the Pages and their respective functionality defined as methods. There is also a sample test-class with name "SampleTest" which contains two test methods that makes the use of the Page Object Pattern defined using "LoginPage" and "HomePage" class


public class LoginPage {
    /**
     * Type username and password into the respective fields and click on submit button.
     * Returns the HomePage class object for successful login
     */
    public HomePage loginAs(String username, String password) {
    }
    /**
     * Used to check whether the login fails for a said username/password.
     * Type username and password into the respective fields and click on submit button.
     * Returns the LoginPage class object for failure login
     */

    public LoginPage loginAsWithFailure(String username, String password) {
    }
    /**
     * Type passed username value into the username field
     * Returns the LoginPage class object
     */
    public LoginPage typeUsername(String username) {
    }
    /**
     * Type passed password value into the password field
     * Returns the LoginPage class object
     */
    public LoginPage typePassword(String password) {
    }
    /**
     * Click on the submit button on the page
     * Returns the HomePage class object
     */
    public HomePage clickOnSubmit() {
    }
}

public class HomePage {
    /**
     * Verifies the said page is the Home page
     */
    public boolean verifyHomePage() {
    }
}

public class SampleTest {
    @Test
    public void verifyThatLoginIsSuccessFul() {
        LoginPage loginPage = new LoginPage();
        loginPage.typeUsername("username");
        loginPage.typePassword("password");
        HomePage homepage = loginPage.clickOnSubmit();
        Assert.assertTrue(homepage.verifyHomePage(),"User not at homepage");
    }

    @Test
    public void verifyThatLoginIsSuccessFulSecond() {
        LoginPage loginPage = new LoginPage();
        HomePage homepage = loginPage.typeUsername("username")
                                     .typePassword("password")
                                     .clickOnSubmit();
        Assert.assertTrue(homepage.verifyHomePage(),"User not at homepage");
    }
}
As you can see from the above test-method in the above “SampleTest” class, there two different test-methods. Both the test-methods have the same flow defined in them , the only difference is the way they had been written. Also you can notice that the test are more readable when implemented by following the Page Object model. Without a  Page Object Pattern the tests may have been more cluttered and non-readable.

Advantages of using Page Object pattern:
- Better code management
- Reduced code duplicity
- In case of change in functionality very minimal changes required to be done. Change the respective page method and it will automatically take effect in all test-methods.
- Testcases are more readable.

1 comment: