Using OOP principles in the context of an automation framework

Gulshan Nadaph
4 min readOct 23, 2024

--

ABSTRACTION

Alright, let’s break this down super simple.

Abstraction is like using a TV remote. You press buttons to change channels or adjust the volume, but you don’t need to know how the remote sends signals to the TV. You just see the result.

Now, let’s see how this works in a Selenium Automation Framework.

Imagine you have a big book (your web application) and you want to find specific words (elements on a page). Instead of flipping through the entire book every time, you use a bookmark (locator) to go straight to the page.

In the Page Object Model design pattern:

  • We create a special class (Page Class) where we write down all the bookmarks (locators like id, name, xpath, etc.) and methods (actions you can do on the page).
  • When we write tests, we use these bookmarks to find the words, but we don’t need to know how the bookmarks were created or how they work.

So, in simple terms, we hide the complicated stuff (how the bookmarks work) and just use the easy stuff (the bookmarks themselves) in our tests. This is abstraction!

#2. INTERFACE

You know the basic statement in Selenium: `WebDriver driver = new FirefoxDriver();`

Here’s why we write it that way:

WebDriver is an Interface : Think of an interface like a contract. It says, “Any class that signs this contract must promise to do certain things.” In this case, WebDriver is the contract.

FirefoxDriver is a Class : This is like a specific worker who agrees to follow the contract. FirefoxDriver is a class that knows how to drive the Firefox browser.

Creating a Reference Variable : When we write `WebDriver driver`, we’re saying, “Hey, I need a worker who can follow the WebDriver contract.” The `driver` is just a name tag for this worker.

Initializing the Browser : When we write `new FirefoxDriver()`, we’re hiring a specific worker who knows how to drive the Firefox browser.

So, `WebDriver driver = new FirefoxDriver();` means:
- We’re asking for a worker (`driver`) who can follow the WebDriver contract.
- We’re hiring a specific worker (`new FirefoxDriver()`) who knows how to drive the Firefox browser.

In Java, an interface (like WebDriver) is like a blueprint. It can have methods and variables, but the methods are just promises (abstract) that need to be fulfilled by any class that signs the contract. This allows us to achieve 100% abstraction and multiple inheritance, meaning we can have different workers (like ChromeDriver, FirefoxDriver) all following the same contract (WebDriver).

#3. INHERITANCE

Inheritance in Java is like a family tradition. One class (child) gets all the cool stuff (properties and functionalities) from another class (parent).

Here’s how it works in an Automation Framework:

Base Class: Think of this as the parent. It has all the important stuff like initializing the WebDriver, setting up waits, reading property files, handling Excel files, etc.

Other Classes (Tests, Utility Class): These are the children. They get all the cool stuff from the parent (Base Class) without having to write it all over again.

So, when we say we extend the Base Class in other classes, it means:

  • The child classes (like Tests and Utility Class) inherit all the properties and functionalities from the parent class (Base Class).

In simple terms, inheritance lets us reuse code. We write the important stuff once in the Base Class and then just extend it in other classes to use that stuff. This way, we don’t have to rewrite the same code again and again.

#4. POLYMORPHISM

Polymorphism is like having a Swiss Army knife. It lets you perform a task in multiple ways using the same tool.

Polymorphism is a combination of overloading and overriding.

Let’s see what these mean:

1. METHOD OVERLOADING
- Method Overloading is like having multiple blades in your Swiss Army knife. Each blade (method) has the same name but does different things based on what you need.
- Example: Implicit wait in Selenium. You can set the wait time in SECONDS, MINUTES, HOURS, etc. The method name is the same, but the parameters (time units) are different.
- Another Example: The `Action` class in TestNG. You can perform different actions using methods with the same name but different parameters.
- Yet Another Example: The `Assert` class in TestNG. You can assert different conditions using methods with the same name but different parameters.

So, Method Overloading means having multiple methods with the same name but different parameters.

2. METHOD OVERRIDING
- Method Overriding is like customizing a blade in your Swiss Army knife. You take a blade (method) that already exists and change how it works.
- Example: In Selenium, different drivers (like ChromeDriver, FirefoxDriver) have `get` and `navigate` methods. These methods do the same thing (open a URL) but are implemented differently for each driver.

So, Method Overriding means declaring a method in a child class that already exists in the parent class but changing its implementation.

In simple terms, polymorphism lets us use the same method name to do different things (overloading) or to customize existing methods (overriding).

#5. ENCAPSULATION

Encapsulation is like packing all your tools in a toolbox. It keeps everything neat and together so you can easily find and use what you need.

In an automation framework, all the classes are examples of encapsulation. Here’s how it works:

POM Classes: Think of these as your toolboxes. Inside, you have tools (data members) that you need for your tests.

We declare these tools using @FindBy to locate elements on a web page.

We initialize these tools using a constructor, so they’re ready to use in methods.

So, Encapsulation is a mechanism of binding code and data (variables) together in a single unit (class).

In simple terms, encapsulation helps us keep everything organized. We put all related code and data into one class, making it easier to manage and use.

This simplified diagram shows how all these concepts work together in an automation framework

--

--