Many a times, we come across this term — Why WebDriver is an Interface?
So, in this article, I will explain what exactly is an Interface in Java and how it helps us in our test automation.
Selenium’s idea of making the WebDriver, an Interface, is to provide a better architectural design to manage different browser actions like opening, navigating, clicking, typing, etc. This abstraction allows us to manage different browsers easily without needing to know their internal workings.
What is an Interface in Java?
- An interface in Java acts as a contract or blueprint that classes must follow.
- It contains abstract methods (methods without a body) that must be implemented by any class that chooses to implement the interface.
- Interfaces allow multiple classes to share common behavior (one way to achieve multiple inheritance in Java), promoting flexibility and supporting the key object-oriented programming principle of abstraction.
Implementation and the real behind-the-scene working of an Interface.
Let’s create on interface and name it as Vehicles.
- Now, a Vehicle can be a Car, Truck, Motorcycle, Bus, etc.
- All these vehicles can have different colours, different type, different size, and different top speed.
In the snippet below, we have made four methods: -
- void brandName() — The brand of the vehicle
- void bodyColour() — The colour of the vehicle
- void typeOfVehicle() — The type of the vehicle
- void topSpeed() — The top speed of the vehicle
public interface Vehicles {
void brandName();
void bodyColour();
void typeOfVehicle();
void topSpeed();
}
Notice, that all these methods are abstract, by default. And it does not contain any body. So we do not need to add the keyword ‘abstract’ before them.
A class uses the keyword ‘implements’, to implement an Interface.
Now, we will create different classes such as -
- Car implementing the Vehicles interface.
public class Car implements Vehicles {
@Override
public void brandName() {
System.out.println("Nissan");
}
@Override
public void bodyColour() {
System.out.println("Blue");
}
@Override
public void typeOfVehicle() {
System.out.println("Sedan");
}
@Override
public void topSpeed() {
System.out.println("200 km/hr");
}
}
- Motorcycle implementing the Vehicles interface.
public class Motorcycle implements Vehicles {
@Override
public void brandName() {
System.out.println("Ducati");
}
@Override
public void bodyColour() {
System.out.println("Red");
}
@Override
public void typeOfVehicle() {
System.out.println("Sports Bike");
}
@Override
public void topSpeed() {
System.out.println("300 km/hr");
}
}
These classes will override the methods defined in the interface, providing different implementations tailored to the specific behavior of each vehicle type, demonstrating polymorphism.
All the classes have implemented the interface, and we have provided the simple implementation of the methods at each class-level. So, lets create an object for each Class and invoke the methods.
1.We create an object for the class — Car. We invoked all the available methods.
public class VehiclesTesting {
public static void main(String[] args) {
Car car = new Car();
car.brandName(); // Output - Nissan
car.bodyColour(); // Output - Blue
car.typeOfVehicle(); // Output - Sedan
car.topSpeed(); // Output - 200 km/hr
}
}
2.We create an object for the class — Motorcycle. We invoked all the available methods.
public class VehiclesTesting {
public static void main(String[] args) {
Motorcycle motorcycle = new Motorcycle();
motorcycle.brandName(); // Output - Ducati
motorcycle.bodyColour(); // Output - Red
motorcycle.typeOfVehicle(); // Output - Sports Bike
motorcycle.topSpeed(); // Output - 300 km/hr
}
}
So, let’s focus on some points of the work that we have done so far
- All of the classes has one common interface and that is Vehicle.
- We have defined four methods in the interface, which has no body.
- Each Class (Car and Motorcycle) implemented the Interface — Vehicle, and we have defined our custom implementation of the methods at each Class level — Car and Motorcycle, by overriding them from the interface.
- We later created objects of each class and invoked the methods. Now we know how an Interface acts and provides us a better way to not repeat everything for every implementation.
Understanding the syntax
So the basic syntax we use to create an instance of the driver for Chrome browser or Firefox browser, is below -
WebDriver driver = new ChromeDriver();
WebDriver driver = new FireFoxDriver();
WebDriver — It is an interface. It has all the methods like navigating to the site, getting the current title of the webpage, getting the title of the webpage and many more. Some common methods with which we are already familar are available in this interface itself — void get(String url)String getCurrentUrl();String getTitle();
driver — It is a reference variable named driver of the type WebDriver.
new ChromeDriver() — This part creates a new instance of the ChromeDriver class, which is an implementation of the WebDriver interface specifically designed to control the Google Chrome browser.
Conclusion
In conclusion, understanding the concept of interfaces in Java provides a clear perspective on why Selenium’s WebDriver is designed as an interface.
- By defining common methods for browser interactions — such as opening, navigating, clicking, and typing — WebDriver allows different browser drivers (e.g., ChromeDriver, FirefoxDriver, EdgeDriver) to implement these methods according to their specific behaviors.
- This abstraction ensures that testers can switch between browsers effortlessly, enabling cross-browser automation without modifying the core test logic.
- The flexibility WebDriver offers through its interface-based design greatly simplifies maintaining tests across various browsers, ensuring compatibility and efficiency in test automation.
Top comments (6)
Love how you broke this down with the vehicle analogy, it finally clicked why WebDriver’s interface matters for automation. Did using interfaces this way ever trip you up when switching browser drivers?
Hey @dotallio , Thank you! I'm glad the vehicle analogy helped clarify the concept. Yes, initially, switching between different browser drivers did present some challenges. However, understanding that WebDriver is an interface allowed me to appreciate the abstraction it provides. By programming to the WebDriver interface rather than a specific implementation, I found it easier to switch between browsers like ChromeDriver and FirefoxDriver without altering the core test logic. Keeping my different drivers in switch cases helps me to switch between my required browser.
The WebDriver design in Selenium is a brilliant example of how Java interfaces can be used to achieve flexibility, scalability, and clean separation of concerns in software architecture. By relying on interfaces rather than concrete implementations, the WebDriver API allows users to write browser-agnostic automation code. This means I can write my tests once and run them across Chrome, Firefox, Edge, or even headless browsers, just by switching the driver implementation—without changing the core logic.
Hey @deividas_strole , yup, absolutely right! :)
pretty cool seeing all the working code and then tying it back to selenium - i learn this stuff so much better when i see real examples. you ever find yourself needing hands-on code to really get stuff, or you good with docs and theory?
Hey @nathan_tarbert , yes, for me the hands-on code really helps to understand the workflow along with the some documentation.