Design Patterns in Automation Framework

On This Page Pre-requisitesPage Object Model Design PatternApril 13, 2026 · 15 min read · Testing Guide

Design Patterns in Automation Framework

As automation suites grow larger, amorphous codification frequently leads to duplication, fragility, and difficult maintenance. Applying proven design figure brings construction and consistency, making fabric more recyclable, scalable, and leisurely to negociate.

Overview

Importance of Design Patterns in Test Automation

  • Reduces code duplication and fragility.
  • Improves code readability, maintainability, and scalability.

Page Object Model (POM)

  • Encapsulates UI elements and interactions.
  • Enhances test maintenance, reduce code duplication
  • Increases code readability and reusability.

Factory Design Pattern

  • Manages object creation efficiently.
  • Simplifies examine data direction.

Facade Design Pattern

  • Provides a simplified interface for complex subsystems.
  • Reduces test handwriting complexity.

Singleton Design Pattern

  • Restricts reduplicate class object instances.
  • Improves performance and memory use.

Fluent Page Object Model

  • Improves the legibility of tests.
  • Makes test scripts more expressive.

This guide introduces several proven plan patterns that help structure automation fabric for maintainability, scalability, readability, and reusability.

Pre-requisites

Step 1Add the required dependence inpom.xmlfile for a Maven project or add the required jars into project classpath

This article has code snipping and to get the consummate code for all the Design Pattern model explained in this article you can refer to thisgithub secretary

For a Maven projection add the “Selenium Java” and “WebDriverManager” colony:

& lt; dependencies & gt; & lt; dependency & gt; & lt; groupId & gt; org.seleniumhq.selenium & lt; /groupId & gt; & lt; artifactId & gt; selenium-java & lt; /artifactId & gt; & lt; version & gt; 3.141.59 & lt; /version & gt; & lt; /dependency & gt; & lt; dependency & gt; & lt; groupId & gt; io.github.bonigarcia & lt; /groupId & gt; & lt; artifactId & gt; webdrivermanager & lt; /artifactId & gt; & lt; variant & gt; 5.2.1 & lt; /version & gt; & lt; /dependency & gt; & lt; /dependencies & gt;

Step 2Add/ update Java JRE edition to 8 for the working project directory.

Step 3Add the TestNG library to the working project directory.

Page Object Model Design Pattern

too known as POM is the most popular structural design pattern in web/mobile automation.

When working in an Agile environment we should constantly be ready to apply changes in the software and finally in the automation codification base. When any prerequisite is changed/deleted/added we need to update automation codification as easily to keep it up and running. If any element is changed in one webpage which is used by 20 test grade files in the automation framework, we necessitate to update at 20 different places if POM design is not postdate.

POM simplifies this and assist to update at one single location which will be used by those 20 different examination class files.

In this pattern pattern web pages are represented as classes. Web page elements are define as variables and user interaction are defined as methods. For model, theLoginPageclass would have locators such asusername, password, loginbtnand methods such aslogin (String username, String password).

Test grade use methods of these page assort whenever it needs to interact with the UI of the page with the assist of the object of the several page class. If any component is update in any page, we just need to update the locator/ method of that page class only.

Page Object is a class that represents a web page and holds the web page component and action methods. Page Factory is a way to format the web elements we want to interact with within the page aim when you make an instance of it.

LoginPage lp=new LoginPage (driver); // Creating object of page class at test class level Pagefactory.initElements (driver, this); // Initialising the web elements in page class.

Below diagram shows the effectuation of POM Design pattern for essay valid login and search scenarios in an ecommerce website.

Below implementation helps to understand Page Object Model design pattern with the helper of a demo ecommerce website (http: //automationpractice.com/index.php)

Step 1 Create a groundwork categoryand add driver initialization, and launch URL code insideinit() method.

public form BaseClass {static WebDriver driver; static String browserName = `` chrome ''; static String url = `` http: //automationpractice.com/index.php ''; public static WebDriver init () {if (browserName.equalsIgnoreCase (`` chrome '')) {WebDriverManager.chromedriver () .setup (); driver = new ChromeDriver ();} else if (browserName.equalsIgnoreCase (`` firefox '')) {WebDriverManager.firefoxdriver () .setup (); driver = new FirefoxDriver ();} driver.manage () .deleteAllCookies (); driver.manage () .window () .maximize (); driver.get (url); return driver;}}

Step 2 Create HomePage, LoginPage, and SearchPage. Add constructor, locators and methods which quiz classes can use to interact with the AUT.

Below is a code snip forHomePage. Likewise createLoginPage and SearchPage.

public stratum HomePage {WebDriver driver; @ FindBy (css = `` a.login '') private WebElement signIn; @ FindBy (css = `` input # search_query_top '') private WebElement lookup; @ FindBy (xpath = `` //button [@ name='submit_search '] '') c individual WebElement seacrhIcon; @ FindBy (css = `` a.logout '') private WebElement signOut; public LoginPage clickSignIn () {signIn.click (); return new LoginPage (driver);} public SearchPage search (String textbook) {search.sendKeys (text); seacrhIcon.click (); return new SearchPage (driver);} public boolean logoutisDisplayed () {return signOut.isDisplayed ();} public HomePage (WebDriver driver) {PageFactory.initElements (driver, this);}}

Step 3 Create LoginTestand create objects of requiredPOMstratum and use it to name methods of respectivePOMclasses to perform valid login scenario.

public class LoginTest {WebDriver driver; LoginPage lp; HomePage hp; SearchPage sp; @ BeforeTest public emptiness setUp () {driver=BaseClass.init (); hp=new HomePage (driver); lp=new LoginPage (driver); sp=new SearchPage (driver);} @ Test (priority = 1) public void validLogin () {hp.clickSignIn (); lp.login (`` & lt; username & gt; '', `` & lt; word & gt; ''); driver.manage () .timeouts () .implicitlyWait (3, TimeUnit.SECONDS); Assert.assertTrue (hp.logoutisDisplayed ());}}

Here, to validate login, we have create objects forHomePage, LoginPageand so used it to call their respective methodshp.clickSignIn () and lp.login ().

Page Object Model design pattern enhances test care, reduces codification duplication, and increases code readability and reusability. It is an object-oriented class that serves as an interface to a page of the Application Under Test (AUT). Page object encapsulate web component, or other course members and ply access to wrapper method that hide all the logic.

Here ’ s how you can implement:
& # 8211; & # 8211; & # 8211; & # 8211; & # 8211; & # 8211;

Factory Design Pattern

Factory Design Pattern is one of the most used creational patterns as it provides one of the best mode to create an object. The condition factory hither means that there should be a stratum with a factory method which deals with all the creational clobber.

SUSA automates exploratory testing with persona-driven behavior, catching bugs that scripted automation misses.

In this pattern, there is a superclass with multiple subclasses and base on the user stimulant at test class tier, it returns one of the subclasses. In former words, it is expend to make an object from one of the possible classes that extends a mutual parent class/ implements an interface. The instantiation logic would be the responsibleness of the grade that is pass the parent class thereby it hides the complex code at examination tier. As a exploiter, we merely postulate to make an object of this class and use it in the exam class to call the appropriate method holding the job logic.

Below diagram shows the implementation of Factory Design pattern in creation of Webdriver object in Selenium framework.

 

Below implementation shows the concept of Factory Design Pattern in order to get desired driver representative

Step 1Create an abstractionist class asDriverManager. Create a methodgetDriverwhich should regress a driver objective.

public abstract class DriverManager {protected WebDriver driver; public WebDriver getDriver () {homecoming driver;}}

Step 2 Create a ChromeDriverManagercategory which will extend theDriverManager class.

public class ChromeDriverManager extend DriverManager {public ChromeDriverManager () {WebDriverManager.chromedriver () .setup (); driver = new ChromeDriver ();}}

Step 3 Create a DriverManagerFactorystratum and add a methodgetManager (& lt; driver typewrite & gt;). This class would take the browser value whatever the user has request for in test class, create the respective driver and return it.

public family DriverManagerFactory {public static DriverManager getManager (DriverType type) {DriverManager driverManager = null; switch (type) {case CHROME: driverManager = new ChromeDriverManager (); case FIREFOX: driverManager = new FirefoxDriverManager (); case EDGE: driverManager = new EdgeDriverManager (); nonpayment: interruption;} return driverManager;}}

Step 4Create an enum asDriverTypeand add all the required browser types.

public enum DriverType {CHROME, FIREFOX, EDGE, SAFARI;}

Step 5Lastly make a test classFactoryDesignTestwhich will usedriverManager.getDriver ()method to convey the requested driver instance.

public class FactoryDesignTest {DriverManager driverManager; WebDriver driver; @ BeforeTest public void beforeTest () {driverManager = DriverManagerFactory.getManager (DriverType.CHROME); driver=driverManager.getDriver ();} @ Test public void verifyBStackDemoAddToCart () {driver.get (`` https: //bstackdemo.com/ ''); List & lt; WebElement & gt; addToCartBtns = driver.findElements (By.cssSelector (`` div.shelf-item__buy-btn '')); addToCartBtns.get (0) .click (); WebElement chkoutbtn = driver.findElement (By.cssSelector (`` div.buy-btn '')); driver.manage () .timeouts () .implicitlyWait (2, TimeUnit.SECONDS); Assert.assertTrue (chkoutbtn.isDisplayed ());} @ Test public void verifyBStackDemoTitle () {driver.get (`` https: //bstackdemo.com/ ''); Assert.assertEquals (driver.getTitle (), `` StackDemo '');} @ Test public void verifyBStackDemoLogo () {driver.get (`` https: //bstackdemo.com/ ''); WebElement logo = driver.findElement (By.cssSelector (`` a.Navbar_logo__26S5Y '')); driver.manage () .timeouts () .implicitlyWait (5, TimeUnit.SECONDS); Assert.assertTrue (logo.isDisplayed ());} @ AfterTest world void afterMethod () {driver.quit ();}}

Instead of creating an object ofDriverManagerclass by employ the new keyword, here we are callinggetManagerstatic method ofDriverManagerfactorywhich is returning an objective ofDriverManagerclass (appropriate browser driver example)

In next, if you need to add any new browser, say Firefox, you can create aFirefoxDriverManagerclass and add all the driver instantiation details in it like we did inChromeDriverManager

You can use Factory Design Pattern when you need to encapsulate the complexity of create an target. This pattern is easy extendible without altering existing codification. This pattern serves one of the best ways to create an target where object conception logic is hidden from the client/user.

Facade Design Pattern

Facade design pattern comes under structural design figure. It provides a simple interface to deal with complex codification. In this pattern we create a frontal grade which has methods that combine activity executed on different pages. This is an extension to the Page Object Model pattern.

Following model can help you underFacade in a layman sentience.

When we see any restaurant to order our favourite food, we are not cognizant of what cuisine the restaurant serve unless we see the menu card or ask the waiter about it. We are just interested in ordering the food by expend a waiter/menu card as the interface (facade) and do not vex about how it is actually being prepared in the kitchen.

Let us consider an example of online shopping in an ecommerce website (http: //automationpractice.com/index.php), where a customer has to add some production to drag and do a checkout for payment. Customer has to first login to the covering, then add merchandise to cart, checkout, add address and so checkout for defrayment.

To hide this complexness of visiting various pages and interacting with it, we can create a facade family and all the requisite business logic in a method.

Below diagram showcase the Facade design pattern

To automate the above scenario with Facade Design Pattern, we need to create the required page classes with locators and class methods as we do in POM Design Pattern. Next, we should create a facade class which has all the complex code effectuation that can be employ by test classes.

Step 1 Create HomePage, LoginPage and SummaryPage, ShippingPage, PaymentPage, and AddressPagewith locators and activity methods.

Below is a code snippet forLoginPage. Likewise the other page can be create.

public class LoginPage {WebDriver driver; public LoginPage (WebDriver driver) {PageFactory.initElements (driver, this);} @ FindBy (css = `` a.login '') private WebElement signIn; @ FindBy (css = `` input # email '') individual WebElement email; public void login (String user, String pass) {signIn.click (); email.sendKeys (user); password.sendKeys (walk); signInBtn.click ();}}

Step 2 Create a PlaceOrderFacadeclass which has method calls to the above advert page classes combined all together in theplaceOrder method.

public class PlaceOrderFacade {WebDriver driver; LoginPage lp; HomePage hp; SummaryPage sp; ShippingPage shp; PaymentPage pp; AddressPage ap; public String placeOrder (WebDriver driver) throws InterruptedException {lp=new LoginPage (driver); System.out.println (`` lp: `` +lp); lp.login (`` & lt; username & gt; '', `` & lt; watchword & gt; ''); hp=lp.clickHomeBtn (driver); sp=hp.addToCartAndProceedToChkOut (0, driver); ap=sp.proceedToCheckOut (driver); shp=ap.proceedToCheckOut (driver); pp=shp.proceedToCheckOut (driver); String cartCount=pp.clickPayByChequeAndConfirm (driver); return cartCount;}}

Step 3 Create FacadeDesignTest which will use the facade class object to call theplaceOrdermethod of facade class.

public class FacadeDesignTest {WebDriver driver; PlaceOrderFacade facade; @ BeforeTest public void setUp () {WebDriverManager.chromedriver () .setup (); driver = new ChromeDriver (); driver.get (`` http: //automationpractice.com/index.php ''); driver.manage () .window () .maximize (); facade=new PlaceOrderFacade ();} @ Test public nullity placeOrder () throws InterruptedException {Assert.assertEquals (facade.placeOrder (driver), `` '');} @ AfterTest world void tearDown () {driver.quit ();}}

PlaceOrderFacadeholds the business logic to call methods of Page classes to accomplish place order functionality. By implementing Facade Design Pattern, you just necessitate to call theplaceOrder method of PlaceOrderFacadein the examination category.

This way you do not experience to make page form object individually in the test family and call the associated methods. Instead, you can create only facade class objects and call the facade method, thereby reducing complexity in the test script. Also, in next if there is any new business logic in between place order stream, you exactly need to update the facade class.

Singleton Design Pattern

Singleton Design Pattern is one of the easiest and straightforward pattern to be implemented in an automation framework. This designing is used when we need to use the same object of a course across the automation framework. It curtail the instantiation of a class to a individual illustration.

Steps to follow to create singleton class:

  1. Declare the constructor of the stratum as‘private’so that no one can instantiate the class outside of it
  2. Declare a unchanging reference variable of class
  3. Declare a static method with return character as an object of this singleton class which should check if the class is already instantiate once.

Below representative facilitate to understand Singleton Design Pattern with Selenium Webdriver.

Step 1 Create a SingletonBaseClass with WebDriverobject initialised as null.

public stratum SingletonBaseClass {individual static WebDriver driver = cipher; private static String browserName= `` chrome ''; public static nullity init () {if (driver == nil) {if (browserName.equalsIgnoreCase (`` chrome '')) {WebDriverManager.chromedriver () .setup (); driver = new ChromeDriver ();} else if (browserName.equalsIgnoreCase (`` firefox '')) {WebDriverManager.firefoxdriver () .setup (); driver = new FirefoxDriver ();}} driver.manage () .deleteAllCookies (); driver.manage () .window () .maximize ();} public static WebDriver getDriver () {return driver;} public motionless void quit () {driver.quit (); driver=null;}}

In SingletonBaseClass,

Webdriver aim has been initialised as static and null.

  • init()stable method is used to initialise the Webdriver object only when the Webdriver object is null. If driver has a value (not been destroyed/ not null),init()method will not be executed and the same driver would be apply for the further execution. This serves the actual purpose of Singleton design pattern
  • getDriver ()still method returns driver object to be used in test class.
  • quit()inactive method quits the driver and do the driver as zippo to demolish the driver object completely.

Step 2 Create SingletonDesignTest class

public class SingletonDesignTest {WebDriver driver1; WebDriver driver2; @ BeforeClass populace emptiness setUp () {SingletonBaseClass.init ();} @ Test (priority = 1) public void verifyBStackDemoTitle () {driver1 = SingletonBaseClass.getDriver (); System.out.println (`` driver1: `` + driver1); driver1.get (`` https: //bstackdemo.com/ ''); Assert.assertEquals (driver1.getTitle (), `` StackDemo '');} @ Test (priority = 2) public void verifyBStackDemoLogo () {driver2 = SingletonBaseClass.getDriver (); System.out.println (`` driver2: `` + driver2); driver2.get (`` https: //bstackdemo.com/ ''); WebElement logo = driver2.findElement (By.cssSelector (`` a.Navbar_logo__26S5Y '')); driver2.manage () .timeouts () .implicitlyWait (5, TimeUnit.SECONDS); Assert.assertTrue (logo.isDisplayed ());} @ AfterClass public emptiness tearDown () {SingletonBaseClass.quit ();}}

In the SingletonDesignTest class, verifyBStackDemoTitle and verifyBStackDemoLogomethods have different driver instances asdriver1 and driver2severally.

Run the above program and observe that Chrome browser will be launched andverifyBStackDemoTitlewill be executed. After this thoughverifyBStackDemoLogohas a different driver initialization, the driver would hold the like value, asinit()method would insure that the driver is not null. Hence it will not create another driver instance and the like browser would be used to executeverifyBStackDemoLogo.

Singleton Pattern can be utilize for creating class which need to restrain twin class object instances. This pattern improves execution and memory utilisation. This pattern is mostly used for Logger, Database connector, or External Resources.

Fluent Page Object Model

Implementing OOPs construct in any automation framework involves deal with heap of page classes and objects. Most of the time, the test codification necessitate to apply these objective and methods becomes very complex. This complexity can be minimised by usingFluent Interface and Method Chaining.

Page Object Model is the most popular and wide used blueprint pattern as it helps in codification legibility and maintainability. And it can be more simplified and decipherable by using Fluent Page Object Model as it uses method chaining.

In this design pattern, every action method in the page class returnthisto implement chaining method for the business logic. This does not mean you can not return other page class objects. You can either returnthis(same class) or another page class too.

Method chaining is a technique where one method is called straight on another method forming a chain-like construction.

Let us understand Fluent Page Object Design Pattern with the help of enrolment example inhttp: //automationpractice.com/index.php website

Step 1 Create HomePage, LoginPage, and RegistrationPagepage classes with locater and action methods.

Code snippet forRegistrationPage. Likewise you can make other page.

public form RegistrationPage {WebDriver driver; @ FindBy (css = `` div # uniform-id_gender2 '') private WebElement mrsRadio; @ FindBy (css = `` input # customer_firstname '') private WebElement firstName; @ FindBy (css = `` input # customer_lastname '') individual WebElement lastName; @ FindBy (css = `` input # passwd '') private WebElement watchword; @ FindBy (css = `` input # firstname '') individual WebElement addFirstName; @ FindBy (css = `` input # lastname '') private WebElement addLastName; @ FindBy (css = `` input # metropolis '') private WebElement metropolis; @ FindBy (css = `` input # postcode '') individual WebElement postcode; @ FindBy (css = `` button # submitAccount '') private WebElement registerBtn; RegistrationPage (WebDriver driver) {this.driver=driver; PageFactory.initElements (driver, this);} public RegistrationPage selectFemaleTitle () {System.out.println (`` driver; `` +driver); mrsRadio.click (); return this;} public RegistrationPage enterFirstName (String first) {firstName.sendKeys (first); return this;} public RegistrationPage enterLastName (String last) {lastName.sendKeys (final); return this;} public RegistrationPage enterPassword (String walk) {password.sendKeys (walk); return this;} public RegistrationPage enterAddFirstName (String first) {addFirstName.sendKeys (first); revert this;} public RegistrationPage enterAddLastName (String last) {addLastName.sendKeys (last); return this;} public RegistrationPage enterCity (String cityName) {city.sendKeys (cityName); return this;} public RegistrationPage enterCode (String office) {postcode.sendKeys (post); return this;} public HomePage clickRegister () {registerBtn.click (); return new HomePage (driver);} public inactive RegistrationPage using (WebDriver driver) {retrovert new RegistrationPage (driver);}}

In the RegistrationPagepage class, methods such asenterFirstName, enterLastName and enterPassword return this and clickRegister returns a HomePageobject. This evidence that it is not required for the methods to always revertthis.

Step 2 Create FluentDesignTesttest class

public class FluentDesignTest {public void register () {RegistrationPage.using (driver) .selectFemaleTitle () .enterFirstName (`` Peter '') .enterLastName (`` John '') .enterPassword (`` Test @ 123 '') .enterAddFirstName (`` Peter '') .enterAddLastName (`` John '') .enterCity (`` Los Angeles '') .enterCode (`` 88205 '') .clickRegister ();}}

In the above examination class, we are not make objective of page classes to access the associated method. Instead, a single concatenation is created to phone all the required methods of a page class in one yell itself.

The silver-tongued page objectsimportantlybetter the readability of tests. Also, it is quite easy to write tests with Fluent fashion.

Conclusion

As an mechanization tester, you might arrive across several problems in framework on a daily basis and sometimes you might do a quick fix at exam level to keep the exam execution up and running. However, this solution may not last for long. It is recommended that QAs should name problems and try to fix it at base level by creating common housecoat methods that can be used by multiple test form.

You should also figure out if this problem can be solved by implementing proper design patterns and try to enforce it in the early stage of automation framework growing. Constantly evaluating the problems and update the automation code/structure is the key for a successful automation framework.

Hence, choosing and implement the correct Design Pattern which suits your test automation requirements is the key to efficient testing.

Using for web examination and for roving app testing, you can seamlessly incorporate your,,, Puppeteer,, and tests to make mechanisation testing easier through your craved Design Pattern. Not only that, you can speed up your tests by 30x with to expand your test and browser reporting without compromising on build multiplication.

Tags
40,000+ Views

# Ask-and-Contributeabout this topic with our Discord community.

Related Guides

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free