top of page

Welcome
to NumpyNinja Blogs

NumpyNinja: Blogs. Demystifying Tech,

One Blog at a Time.
Millions of views. 

Building Selenium based automation framework using Java OOPS concepts

Jan 23, 2025
4 min read

Building a Selenium automation framework requires a strong foundation in Object-Oriented Programming (OOP) principles. By incorporating OOPs concepts like encapsulation, inheritance, abstraction, and polymorphism, we can create a scalable, maintainable, and reusable framework.


This blog explores best practices for building such a framework using Selenium, TestNG, and Java.

Let’s learn about these OOPs concepts and incorporate them into the automation framework.


What are Object-Oriented Programming (OOP) principles and how they matter in automation frameworks?

Key concepts of OOPS :

  • Encapsulation

  • Inheritance

  • Abstraction

  • Polymorphism


Class

Class is a user-defined data type, which holds data members and member functions and can be accessed by creating an instance of that class. It’s like a blueprint for an object.

class Car {

    // Properties (data members)

    int wheels;        

    int speedLimit;     

    // Constructor to initialize the properties

    public Car(int wheels, int speedLimit, double mileage)

    {

        this.wheels = wheels;

        this.speedLimit = speedLimit;

      } 

    // Method to display car details(member function)

    public void displayDetails()

    {

        System.out.println("Wheels: " + wheels);

        System.out.println("Speed Limit: " + speedLimit + " km/h");       

      }

}

Object

An object is an instance of a class. Data members and methods of a class cannot be used directly. We need to create an object (or instance) of the class to use them. In simple terms, they are the actual world entities that have a state and behavior.

public class Main {

     public static void main(String[] args)

      {

        // Create a Car object

        Car camry = new Car(4, 200, 15.5);       

        // Display car details

        System.out.println(" Camry Details:");

         camry.displayDetails();       

    } }

Encapsulation

Encapsulation is a process of binding the data members (attributes) and member functions together. It restricts direct access to important data.

The best example of the encapsulation concept is making the data members of a class private, and methods as public to access through an object. In this case, only methods can access private data.

// Java Program to demonstrate- Encapsulation

class Person {  

 

    // Encapsulating the name and age

   // only approachable and used using methods

    private String name;

    private int age;

 

    public String getName() { return name; }

    public void setName(String name) {

    this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age = age; }

}

public class Main {

    public static void main(String[] args) {

        Person personObj = new Person();

        // person object created

        person.setName("John");

        person.setAge(30);

       // Using methods to get the values from the        variables

       System.out.println("Name: " + person.getName());

        System.out.println("Age: " + person.getAge());

    }

}

 

Inheritance

Inheritance is a process by which we can reuse the functionalities of existing classes to new classes. When a class is inherited from another class (base class/Super class), it (derived class/Sub class) obtains all the properties and behaviors of the base class.

class Animal {

   public void eat() {

        System.out.println("Animal is eating");  }

   }

class Dog extends Animal {

 public void bark() {

      System.out.println("Dog is barking");  }

  }

public class Main {

       public static void main(String[] args) {

         Dog myDog = new Dog();

          myDog.eat(); // Inherited from Animal // Animal is eating

                myDog.bark(); // Specific to Dog   // Dog is barking

  } }

Abstraction

Abstraction focuses on hiding the implementation details and exposing only the essential features.

public abstract class Shape {

    abstract void draw(); }

public class Circle extends Shape {

    @Override

     void draw() { System.out.println("Drawing a circle");

    }}

public class Rectangle extends Shape {

     @Override

     void draw() {  System.out.println("Drawing a rectangle");

    }

}

public class Main {

    public static void main(String[] args) {

                 Shape obj = new Circle();

                obj.draw();  // Outputs “Drawing a circle”          obj = new Rectangle();

                obj.draw(); // Outputs “Drawing a rectangle”

  } }

Polymorphism

The term "polymorphism" means "many forms". In object-oriented programming, polymorphism is useful when you want to create multiple forms with the same name of a single entity.

class Animal {  public void animalSound() {                System.out.println("The animal makes a sound");  }}class Pig extends Animal {

 @Override   public void animalSound() {                System.out.println("The pig says: wee wee");   }}class Dog extends Animal

{

  @Override  public void animalSound() {        System.out.println("The dog says: woof woof");}

}

public class PolymorphismExample {

public static void main(String[] args) {

     Animal animal = new Animal();

     animal.makeSound(); //the animal makes sounds

     Dog dog = new Dog();

     dog.makeSound();     //the dog barks

     animal = new Cat();

     animal.makeSound(); //the cat meows

    }

}

Here’s how each OOP concept applies to Selenium automation frameworks:


TestNG framework























Encapsulation: Groups related actions and data into classes, making the code modular and easy to manage.

Example : SignInPage.java class from the above framework, we can achieve encapsulation by declaring the web elements as private and methods accessing these elements as public.
























Inheritance: Enables code reuse by allowing test classes to inherit common behaviors from a base class.

Example : SignInPageEvents.java class inherits setUP and tearDown methods from the Base class and executes before and after each @Test methods.

Polymorphism: Provides flexibility to handle multiple implementations through method overriding or interfaces.

Example: In BrowserFactory.java class, WebDriver is an interface in Selenium. ChromeDriver, FirefoxDriver, and EdgeDriver are concrete classes that implement the WebDriver interface.By using WebDriver as the return type and assigning instances of ChromeDriver, FirefoxDriver, or EdgeDriver to it, the method exhibits runtime polymorphism. This allows the code to work with any browser driver that implements the WebDriver interface, making it flexible and extensible.

Abstraction: Simplifies complex logic by exposing only essential details, keeping the rest hidden.

Example: ReportGenerator.java is abstract base class that defines a high-level blueprint for generating reports with the abstract method generateReport() , this method has no implementation. The subclasses that extends this abstract class can have the implementation for the method  generateReport(). This is how abstraction hides the specifics of how reports (e.g., HTML or PDF) are generated, while requiring subclasses to provide their own implementation.

The complete code for this Selenium TestNg framework is available on my GitHub repository. [👉 View the Project on GitHub (https://github.com/geetak23/OOPs_Demo_Prj) ]


Building Selenium Java framework using OOP concepts ensures scalability, maintainability, and reusability. Start small, iterate as needed, and continuously enhance your framework with advanced features.


I hope you found this blog as insightful and enjoyable to read as I did while writing it. Happy learning!






 
 

+1 (302) 200-8320

NumPy_Ninja_Logo (1).png

Numpy Ninja Inc. 8 The Grn Ste A Dover, DE 19901

© Copyright 2025 by Numpy Ninja Inc.

  • Twitter
  • LinkedIn
bottom of page