How to use ThreadLocal for parallel testing in selenium?

Parallel execution in Selenium can lead to issues like WebDriver session conflicts if multiple threads try to access the same driver instance. To avoid this, we can use ThreadLocal<WebDriver>, which provides each thread its own isolated WebDriver instance.

We achieve this by:

  • Creating a utility class DriverFactory where we:
    • Initialize the driver and assign it using ThreadLocal.set() in initDriver().
    • Retrieve the thread-safe driver using ThreadLocal.get() in getDriver().
    • Clean up the driver using quitDriver() and ThreadLocal.remove() to avoid memory leaks.

Then, we use TestNG’s @BeforeMethod and @AfterMethod annotations in a BaseTest class to call these driver setup and teardown methods for every test method.


✅ DriverFactory.java

package utils;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
// import io.github.bonigarcia.wdm.WebDriverManager; // Optional for auto-setup

public class DriverFactory {

// ThreadLocal variable for WebDriver
private static final ThreadLocal<WebDriver> tlDriver = new ThreadLocal<>();

// Initialize WebDriver and set into ThreadLocal
public static void initDriver() {
    // Optional: Setup using WebDriverManager
    // WebDriverManager.chromedriver().setup();
    WebDriver driver = new ChromeDriver();
    tlDriver.set(driver);
}

// Get driver from ThreadLocal
public static WebDriver getDriver() {
    return tlDriver.get();
}

// Clean up after test
public static void quitDriver() {
    WebDriver driver = getDriver();
    if (driver != null) {
        driver.quit();
        tlDriver.remove();
    }
}

}

We are going to call initDriver and quitDriver methods of DriverFactory from BaseTest using BeforeMethod and AfterMethod annotations of testng from BaseTest with the following script

✅ BaseTest.java

package tests;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import utils.DriverFactory;

public class BaseTest {

@BeforeMethod
public void setUp() {
    DriverFactory.initDriver();
}

@AfterMethod
public void tearDown() {
    DriverFactory.quitDriver();
}

}

Created SampleTest class extending BaseTest with different tests to call driver with the following script

✅ SampleTest.java

package tests;

import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import utils.DriverFactory;

public class SampleTest extends BaseTest {

@Test
public void testGoogleSearch() {
    WebDriver driver = DriverFactory.getDriver();
    driver.get("https://www.google.com");
    System.out.println("Page Title is: " + driver.getTitle());
}

@Test
public void testBingSearch() {
    WebDriver driver = DriverFactory.getDriver();
    driver.get("https://www.bing.com");
    System.out.println("Page Title is: " + driver.getTitle());
}

}

testng.xml with specifying SampleTest for execution with the following xml

✅ testng.xml for Parallel Execution

<suite name=”Parallel Suite” parallel=”methods” thread-count=”2″>

<test name=”Parallel Tests”>

<classes>

<class name=”tests.SampleTest”>

</classes>

</test>

</suite>

✅ Notes & Best Practices

  • Use ThreadLocal.remove() in quitDriver() to prevent memory leaks.
  • Use WebDriverManager (optional) to avoid manually setting the driver path.
  • You can extend DriverFactory to support multiple browsers using parameters.
  • Ensure the chromedriver binary is available in your system PATH or configured properly.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Testingtalkslatest.com - A project by CreativeHub IT Solutions.
Contact Us At: support@testingtalkslatest.com
Our Partner websites - Classified Hub , CodesToolbox , Smart Fitness Guide , CodesToolbox , Testing Forum
Scroll to Top
0
Would love your thoughts, please comment.x
()
x