Codementor Events

APPLICATION OF OBJECT-ORIENTED PROGRAMMING PRINCIPLES WHILE DESIGNING TEST AUTOMATION FRAMEWORK

Published Sep 09, 2020
APPLICATION OF OBJECT-ORIENTED PROGRAMMING PRINCIPLES WHILE DESIGNING TEST AUTOMATION FRAMEWORK

Everyone who has ever been a part of the process of designing a Test Automation Framework will understand how crucial it is to know these pillars of object-oriented programming principles to lay the foundation of an efficient and scalable framework.
Most of us understand these concepts theoretically but the real challenge arises when we are supposed to practically use them while designing frameworks. These concepts improve the reusability, remove redundancy, and result in a framework that is easy to maintain.

If you don’t have time to do it right, when will you have time to do it again?
-John Wooden

Encapsulation

It is the mechanism of wrapping the data and methods inside a single unit in a way that the data is not accessible to the outside world.

Look how we can achieve encapsulation in Java :

public class Student {
  private int identificationNumber;

  public void setIdentificationNumber(int id) {
    this.identificationNumber = id;
  }

  public int getStudentId() {
    return identificationNumber;
  }
}

All we need to do is declare the data private(so that other classes cannot access it) and add public methods to deal with this data.

Page Object Model(POM) is a design pattern that encourages encapsulation.
While automating a web application, POM advocates the idea of representing every webpage with a class. The web elements will be present as private data and public methods will be present to perform actions on them. Let's understand more about POM using the below webpage :


image

WebPage showing the profile page of another user searched by logged in user on LinkedIn Platform

Below is the example of page object class for the above webpage with the highlighted web element(About Section) :

public class OtherUserProfilePage {

  private WebDriver driver;
  private By aboutText = By.cssSelector("p.pv-about__summary-text");

  public OtherUserProfilePage(WebDriver driver) {
    this.driver = driver;
  }

  public String getAboutText() {
    return driver.findElement(aboutText).getText();
  }
}

Inheritance

Another important concept which allows one class to inherit the features of some other class. Here features refer to fields and methods.

Below is the Base or Parent Class :

public class Human {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Below is the Derived or Child Class :

public class Employee extends Human {
  private int employeeID;

  public void setEmployeeID(int employeeID) {
    this.employeeID = employeeID;
  }

  public int getEmployeeID() {
    return employeeID;
  }
}

Employee class will be able to use the properties of Human class. Look at the below example:

Employee emp = new Employee();
emp.setName("PARUL KATARIA");

image

WebPage showing the profile page of logged in user on LinkedIn Platform


image

WebPage showing the profile page of another user searched by logged in user on LinkedIn Platform

Look closely at the above web pages and you will be able to see that there are certain sections which are common to both the webpages(it has been highlighted by using red-colored boxes) and in addition to that there are buttons which are specific to a certain webpage(it has been highlighted by using yellow-colored boxes).
Inheritance can play a vital role here and avoid duplicacy of code. Follow the approach below while designing page objects in such scenarios :

There should be a page class that will include all the elements which are common to both the pages.
Name is being displayed on both the profile pages so it can be a part of this class which will act as a base class.

public class ProfilePage {

  public WebDriver driver;
  private By userName = By.cssSelector("ul.pv-top-card--list li");

  public ProfilePage(WebDriver driver) {
    this.driver = driver;
  }

  public String getUserName() {
    return driver.findElement(userName).getText();
  }
}

There will be a class which will contain web elements specific to the profile page of logged in user and it will inherit the ProfilePage class."Add Profile Section" element will be a part of this class.

public class LoggedInUserProfilePage extends ProfilePage {

  private By addProfileSectionButton = By.xpath("//span[text()='Add profile section']");

  public void clickAddProfileSectionButton() {
    driver.findElement(addProfileSectionButton).click();
  }
}

There will be another class which will contain web elements specific to the profile page of another user searched by logged in user and it will inherit the ProfilePage class."Message" element will be a part of this class.

public class OtherUserProfilePage extends ProfilePage {

  private By messageButton = By.xpath("//a[text()='Message']");

  public void clickAddProfileSectionButton() {
    driver.findElement(messageButton).click();
  }
}

Polymorphism

Polymorphism means "having several forms" and is one of the OOPs features that allow us to perform a single action in different ways.

Below is the example of Polymorphism:

public class City {
  int getBusStops() {
    return 0;
  }
}

class Delhi extends City {
  int getBusStops() {
    return 10000;
  }
}

class Gurgaon extends City {
  int getBusStops() {
    return 2000;
  }
}

class TestPolymorphism {
  public static void main(String args[]) {
    City city;
    city = new Delhi();
    System.out.println("Bus stops in Delhi: " + city.getBusStops());
    city = new Gurgaon();
    System.out.println("Bus stops in Gurgaon: " + city.getBusStops());
  }
}

Let's shift our focus on the same classes which were used in the last concept.
ProfilePage is the base class while LoggedInUserProfilePage and OtherUserProfilePage are the derived classes.

public class Test {
  public ProfilePage navigateToProfilePage(String name, String loggedInUserName) {
    if (name.equals(loggedInUserName))
      return new LoggedInUserProfilePage();
    else
      return new OtherUserProfilePage();
  }
}

Abstraction

Abstraction is aimed at displaying only that information which is essential while the rest of the details can be hidden.

Look how we can achieve abstraction in Java :

package abstraction;

public interface Vehicle {
  int getNumberOfWheels();
  void setNumberOfWheels(int wheels); 
}
public class Car implements Vehicle {
  private int numberOfWheels;

  public void setNumberOfWheels(int numberOfWheels) {
    this.numberOfWheels = numberOfWheels;
  }

  public int getNumberOfWheels() {
    return numberOfWheels;
  }
}

Interface comes handy if there is a situation of multiple inheritance as Java doesn't allow a class to extend more than one class. In addition to that, Interface helps in achieving 100% abstraction.

public interface GenericFunctions{
  public List<WebElement> getItems();

  public int itemsCount();
}

public class LoggedInUserProfilePage extends ProfilePage implements GenericFunctions {
  private By peopleAlsoViewedList = By
      .cssSelector("div.pv-deferred-area__content ul.pv-profile-section__section-info li");

  public List<WebElement> getItems() {
    return driver.findElements(peopleAlsoViewedList);
  }

  public int itemsCount() {
    return getItems().size();
  }
}

Hope you would have enjoyed reading this post!

Discover and read more posts from parul kataria
get started
post commentsBe the first to share your opinion
Show more replies