Skip to content

Make Selenium Easy

And Keep It That Way

  • Home
  • Share
  • Toggle search form

How To Use Singleton Class to Manage Instance Variables in Automation Framework – Java

Posted on 03/21/2025 By admin

In the previous post, we have seen how maximum beginners and experienced Selenium professionals apply inheritance with TestNG annotations while setup test scripts and end up with encountering NullPointerException. We have solved NullPointerException by converting instance variables to Static variables.

We can solve the above problem using a Singleton design pattern as well. Let’s learn about it.

TestNG version used as below:-

  org.testng testng 7.1.0 test

Let’s think of a scenario. A money bank may have many branches and many registered customers can withdraw or deposit or access there account at any time any place. Bank has a centralized common server where details of each customer are stored. If a new branch is opened it will also access data from the same server. If a brach is closed then also server will have customer’s data. In short, there is a common place where the state of data is stored.

We can consider an example of money withdrawal from ATM. If a customer tries to withdraw money simultaneously from two places, surely it will fail in one place because they also have a common place where data is kept updated. We can call that common place as a Singleton class.

When we develop a class in such a way that it can have the only instance at any time, is called a Singleton class. If a class is not instantiated then instantiate it and if the class is already instantiated return the same instantiated instance of the class. If we allow only one instance of any class that means we will have a shared object (somewhat how does a class variable or static variable works). This will solve our problem explained in the previous post. Variables initialized in TestNG annotated method will be stored in a common object for usage wherever we want.

package SecondTestNullPointerExceptionWithSingleton;

public class SharedVariables {

        // Private instance of class
        private static final SharedVariables instance = new SharedVariables();

        // Private constructor to control object creation of class
        private SharedVariables() {
        }

        // Return unidealized instance of class 
        public static SharedVariables getInstance() {
                return instance;
        }

        // A private variable with getter and setter methods
        private String someVariable;

        public String getSomeVariable() {
                return someVariable;
        }

        public void setSomeVariable(String someVariable) {
                this.someVariable = someVariable;
        }
}
package SecondTestNullPointerExceptionWithSingleton;

import org.testng.annotations.BeforeSuite;

public class Setup {

        // Get same instance of SharedVariables always
        SharedVariables sharedVariables = SharedVariables.getInstance();

        @BeforeSuite
        public void setupVariable() {
                System.out.println("Executing setupVariable...");
                sharedVariables.setSomeVariable("someValue");
        }

}
package SecondTestNullPointerExceptionWithSingleton;

import org.testng.annotations.Test;

public class FirstTestNGClass extends Setup{
        
        @Test
        public void firstMethodOfFirstTestNGClass()
        {
                System.out.println("Executing firstMethodOfFirstTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
        }
        
        @Test
        public void secondMethodOfFirstTestNGClass()
        {
                System.out.println("Executing secondMethodOfFirstTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
        }
}
package SecondTestNullPointerExceptionWithSingleton;

import org.testng.annotations.Test;

public class SecondTestNGClass extends Setup{
        
        @Test
        public void firstMethodOfSecondTestNGClass()
        {
                System.out.println("Executing firstMethodOfSecondTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
        }
        
        @Test
        public void secondMethodOfSecondTestNGClass()
        {
                System.out.println("Executing secondMethodOfSecondTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
        }
}


        

[RemoteTestNG] detected TestNG version 7.0.1
Executing setupVariable...
Executing firstMethodOfFirstTestNGClass...
Value of someVariable is : someValue
Executing secondMethodOfFirstTestNGClass...
Value of someVariable is : someValue
Executing firstMethodOfSecondTestNGClass...
Value of someVariable is : someValue
Executing secondMethodOfSecondTestNGClass...
Value of someVariable is : someValue

===============================================
Suite
Total tests run: 4, Passes: 4, Failures: 0, Skips: 0
===============================================

You may ask in the above Singleton class creating variables in advance will be difficult and how can we save random variables. We can make out singleton class more advance with Map where will give user flexibility to save any data. This implementation even helps in sharing context among tests.

package SecondTestNullPointerExceptionWithSingleton; import java.util.HashMap; public class SharedVariablesMap { // Private instance of class private static final SharedVariablesMap instance = new SharedVariablesMap(); private static HashMap dataStore = new HashMap(); // Private constructor to control object creation of class private SharedVariablesMap() { } // Return unidealized instance of class public static SharedVariablesMap getInstance() { return instance; } public void store(String key, String value) { dataStore.put(key, value); } public Object get(String key) { return dataStore.get(key); }
}
package SecondTestNullPointerExceptionWithSingleton;

import org.testng.annotations.BeforeSuite;

public class Setup {

        // Get same instance of SharedVariables always
        SharedVariables sharedVariables = SharedVariables.getInstance();
        SharedVariablesMap sharedVariablesMap = SharedVariablesMap.getInstance();

        @BeforeSuite
        public void setupVariable() {
                System.out.println("Executing setupVariable...");
                sharedVariables.setSomeVariable("someValue");
                sharedVariablesMap.store("Name", "Amod");
        }

}
package SecondTestNullPointerExceptionWithSingleton;

import org.testng.annotations.Test;

public class FirstTestNGClass extends Setup{
        
        @Test
        public void firstMethodOfFirstTestNGClass()
        {
                System.out.println("Executing firstMethodOfFirstTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
                System.out.println("Value of name is :"+ sharedVariablesMap.get("Name"));
        }
        
        @Test
        public void secondMethodOfFirstTestNGClass()
        {
                System.out.println("Executing secondMethodOfFirstTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
                System.out.println("Value of name is :"+ sharedVariablesMap.get("Name"));
        }
}
package SecondTestNullPointerExceptionWithSingleton;

import org.testng.annotations.Test;

public class SecondTestNGClass extends Setup{
        
        @Test
        public void firstMethodOfSecondTestNGClass()
        {
                System.out.println("Executing firstMethodOfSecondTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
                System.out.println("Value of name is :"+ sharedVariablesMap.get("Name"));
        }
        
        @Test
        public void secondMethodOfSecondTestNGClass()
        {
                System.out.println("Executing secondMethodOfSecondTestNGClass...");
                System.out.println("Value of someVariable is : "+ sharedVariables.getSomeVariable());
                System.out.println("Value of name is :"+ sharedVariablesMap.get("Name"));
        }
}

There is no change in TestNG xml.

[RemoteTestNG] detected TestNG version 7.0.1
Executing setupVariable...
Executing firstMethodOfFirstTestNGClass...
Value of someVariable is : someValue
Value of name is :Amod
Executing secondMethodOfFirstTestNGClass...
Value of someVariable is : someValue
Value of name is :Amod
Executing firstMethodOfSecondTestNGClass...
Value of someVariable is : someValue
Value of name is :Amod
Executing secondMethodOfSecondTestNGClass...
Value of someVariable is : someValue
Value of name is :Amod

===============================================
Suite
Total tests run: 4, Passes: 4, Failures: 0, Skips: 0
===============================================

You can download/clone the above sample project from here.

If you have any doubt, feel free to comment below.If you like my posts, please like, comment, share and subscribe.#ThanksForReading

#HappyLearning

Uncategorized

Post navigation

Previous Post: make selenium easy rest assured tutorial
Next Post: Selenium Quiz

Related Posts

Hierarchy of Selenium Classes and Interfaces – Make Selenium Easy Uncategorized
selenium tutorials Uncategorized
OverloadedParaTestNg – Make Selenium Easy Uncategorized
December 16, 2017 – Make Selenium Easy Uncategorized
Environment Variables in Postman Uncategorized
Hierarchy of Selenium Classes and Interfaces – Make Selenium Easy Uncategorized

Recent Posts

  • Getting Started with Selenium 4: What Is New and How to Upgrade from Selenium 3
  • Manual Testing
  • Baby Steps To Become Efficient Selenium-Java Automation Tester
  • Features of Selenium 4.0.0 Release – Java Binding
  • Part 1: Handling Drop-down Created Using SELECT Tag In Selenium

Recent Comments

No comments to show.

Archives

  • April 2026
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • April 2024
  • March 2024
  • February 2024
  • December 2023
  • October 2023
  • August 2023
  • November 2022
  • September 2022
  • August 2022
  • July 2022
  • May 2022
  • March 2022
  • October 2021
  • April 2021
  • March 2021
  • January 2021
  • December 2020
  • October 2020
  • September 2020
  • August 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • May 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • January 2018

Categories

  • Getting Started
  • Uncategorized

Copyright © 2026 Make Selenium Easy.

Powered by PressBook Masonry Dark