Parallel Testing in Selenium and TestNG
Parallel Testing is a software testing technique in which multiple test cases, test methods, browser sessions, or test suites are executed simultaneously instead of running one test after another. Parallel testing is widely used in Selenium automation to reduce overall execution time and to validate applications across multiple browsers, operating systems, environments, and test scenarios.
In a Selenium TestNG framework, parallel execution can be configured using TestNG XML, Data Providers, or framework-level thread management. When implemented correctly, parallel testing can significantly improve the efficiency of large regression and cross-browser test suites.
Course Resource: Selenium Training | Register for Course Demo
1. What is Parallel Testing?
Parallel testing means executing multiple independent tests at the same time. In traditional sequential execution, Test A completes before Test B starts. In parallel execution, Test A and Test B can run concurrently on separate threads or browser sessions.
Sequential Execution:
Test A
|
v
Test B
|
v
Test C
|
v
Test D
Parallel Execution:
Test A ──────────┐
Test B ──────────┤
Test C ──────────┤──> Execute at the same time
Test D ──────────┘
The primary purpose of parallel testing is to reduce total test execution time while maintaining reliable and isolated test execution.
2. Why is Parallel Testing Important?
Large Selenium test suites can contain hundreds or thousands of test cases. Executing all tests sequentially can take a significant amount of time. Parallel testing allows independent tests to execute concurrently.
- Reduces overall test execution time.
- Improves regression testing efficiency.
- Supports cross-browser testing.
- Allows multiple test scenarios to run simultaneously.
- Improves CI/CD pipeline execution time.
- Helps utilize available CPU and infrastructure resources.
- Supports scalable automation frameworks.
- Can increase testing throughput.
- Works effectively with Selenium Grid and cloud testing platforms.
3. Sequential Testing vs Parallel Testing
| Feature | Sequential Testing | Parallel Testing |
| Execution | One test after another | Multiple tests concurrently |
| Execution Time | Usually longer | Can be significantly reduced |
| Browser Sessions | Usually limited | Multiple sessions can run concurrently |
| Infrastructure | Lower resource requirement | Higher resource requirement |
| Thread Management | Less important | Very important |
| Test Isolation | Simpler | Must be carefully designed |
| CI/CD | Can take longer | Suitable for large suites |
4. Parallel Testing Flow
Test Suite
|
v
TestNG Scheduler
|
v
Thread Pool
|
+---------- Thread 1 ----------> Test A ---> Browser 1
|
+---------- Thread 2 ----------> Test B ---> Browser 2
|
+---------- Thread 3 ----------> Test C ---> Browser 3
|
+---------- Thread 4 ----------> Test D ---> Browser 4
|
v
Results
|
v
Test Report
TestNG assigns available test executions to threads according to the configured parallelization strategy and thread count.
5. Parallel Testing in Selenium
Selenium WebDriver controls browsers, while TestNG can manage test execution. Selenium itself should not be treated as a replacement for the test runner's parallel execution mechanism. The test framework controls how multiple test invocations are scheduled.
A common Selenium architecture is:
TestNG
|
+---- Thread 1 ----> WebDriver ----> Chrome
|
+---- Thread 2 ----> WebDriver ----> Firefox
|
+---- Thread 3 ----> WebDriver ----> Edge
|
+---- Thread 4 ----> WebDriver ----> Chrome
Each concurrent test should generally have its own isolated WebDriver instance.
6. Parallel Testing with TestNG
TestNG provides XML configuration options for controlling parallel execution. A TestNG suite can specify a parallel mode and a thread count.
<suite name="ParallelSuite" parallel="tests" thread-count="3">
<test name="Chrome Tests">
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
<test name="Firefox Tests">
<classes>
<class name="tests.SearchTest"/>
</classes>
</test>
<test name="Edge Tests">
<classes>
<class name="tests.CheckoutTest"/>
</classes>
</test>
</suite>
The parallel attribute determines the execution strategy, while thread-count controls the maximum number of threads available for parallel execution.
7. Common TestNG Parallel Modes
TestNG provides different levels at which tests can be executed in parallel.
| Parallel Mode | Meaning | Typical Use |
| tests | Execute different <test> blocks in parallel | Cross-browser or independent test groups |
| classes | Execute test classes in parallel | Independent test classes |
| methods | Execute test methods in parallel | Highly independent test methods |
| instances | Execute different test instances in parallel | Factory-based or instance-based tests |
8. Parallel="tests"
When parallel="tests" is used, different TestNG <test> blocks can execute concurrently.
<suite name="BrowserSuite" parallel="tests" thread-count="3">
<test name="Chrome">
<parameter name="browser" value="chrome"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
<test name="Firefox">
<parameter name="browser" value="firefox"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
<test name="Edge">
<parameter name="browser" value="edge"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
This approach is commonly useful for cross-browser testing because each TestNG <test> can represent a different browser configuration.
9. Parallel="classes"
With parallel="classes", different test classes can be executed concurrently.
<suite name="ClassParallelSuite" parallel="classes" thread-count="3">
<test name="Automation Tests">
<classes>
<class name="tests.LoginTest"/>
<class name="tests.SearchTest"/>
<class name="tests.CheckoutTest"/>
</classes>
</test>
</suite>
This approach is useful when test classes are sufficiently independent from one another.
10. Parallel="methods"
With parallel="methods", eligible test methods can execute concurrently.
<suite name="MethodParallelSuite" parallel="methods" thread-count="4">
<test name="Tests">
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
Method-level parallelism can provide high concurrency, but test methods must be designed carefully so that they do not depend on shared mutable state.
11. Thread Count
The thread-count attribute specifies the maximum number of threads that TestNG can use for the configured parallel execution.
<suite name="Suite" parallel="tests" thread-count="4">
For example, a thread count of four allows up to four eligible test executions to run concurrently, subject to the selected parallelization mode and available work.
12. Understanding Threads
A thread is an independent path of execution within a process. In parallel testing, different test tasks can be assigned to different threads.
Thread Pool
|
+---- Thread 1 --> Login Test
|
+---- Thread 2 --> Search Test
|
+---- Thread 3 --> Cart Test
|
+---- Thread 4 --> Checkout Test
The exact scheduling order can vary because thread execution is managed by the runtime and operating system.
13. Simple Parallel Test Example
import org.testng.annotations.Test;
public class ParallelTest {
@Test
public void loginTest() throws InterruptedException {
System.out.println(
"Login Test - Thread: " +
Thread.currentThread().getId()
);
Thread.sleep(1000);
}
@Test
public void searchTest() throws InterruptedException {
System.out.println(
"Search Test - Thread: " +
Thread.currentThread().getId()
);
Thread.sleep(1000);
}
@Test
public void checkoutTest() throws InterruptedException {
System.out.println(
"Checkout Test - Thread: " +
Thread.currentThread().getId()
);
Thread.sleep(1000);
}
}
When method-level parallel execution is configured, the test methods may run on different threads.
14. Parallel Selenium WebDriver Tests
One of the most important principles of parallel Selenium testing is that concurrent test executions should not accidentally share the same WebDriver instance.
Thread 1
|
+-- WebDriver Instance 1
|
+-- Chrome Session 1
Thread 2
|
+-- WebDriver Instance 2
|
+-- Chrome Session 2
Sharing one mutable WebDriver instance across concurrent tests can cause commands from different tests to interfere with each other.
15. Basic Parallel Selenium Example
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class ParallelSeleniumTest {
private WebDriver driver;
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
}
@Test
public void googleTest() {
driver.get("https://www.google.com");
System.out.println(
"Google Test - Thread: " +
Thread.currentThread().getId()
);
}
@Test
public void exampleTest() {
driver.get("https://example.com");
System.out.println(
"Example Test - Thread: " +
Thread.currentThread().getId()
);
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
For reliable concurrent execution, the framework should ensure that each test invocation receives the correct driver instance.
16. ThreadLocal for WebDriver
ThreadLocal is commonly used in Selenium frameworks to maintain a separate WebDriver reference for each executing thread.
public class DriverManager {
private static ThreadLocal<WebDriver> driver =
new ThreadLocal<>();
public static void setDriver(WebDriver webDriver) {
driver.set(webDriver);
}
public static WebDriver getDriver() {
return driver.get();
}
public static void unload() {
driver.remove();
}
}
Each thread can have its own WebDriver reference through the ThreadLocal storage mechanism.
17. ThreadLocal WebDriver Example
public class DriverFactory {
private static ThreadLocal<WebDriver> driver =
new ThreadLocal<>();
public static void initializeDriver() {
driver.set(new ChromeDriver());
}
public static WebDriver getDriver() {
return driver.get();
}
public static void quitDriver() {
WebDriver currentDriver = driver.get();
if (currentDriver != null) {
currentDriver.quit();
driver.remove();
}
}
}
A test class can then obtain the WebDriver associated with the current thread.
18. Parallel Testing with @DataProvider
TestNG Data Providers can also be configured for parallel execution using parallel = true.
@DataProvider(
name = "users",
parallel = true
)
public Object[][] users() {
return new Object[][] {
{"user1"},
{"user2"},
{"user3"},
{"user4"}
};
}
@Test(dataProvider = "users")
public void userTest(String username) {
System.out.println(
Thread.currentThread().getId() +
" : " + username
);
}
Each Data Provider invocation can be scheduled independently, subject to the available thread capacity.
19. Parallel Data Provider with Selenium
@DataProvider(
name = "searchData",
parallel = true
)
public Object[][] searchData() {
return new Object[][] {
{"Laptop"},
{"Mobile"},
{"Headphones"},
{"Keyboard"}
};
}
@Test(dataProvider = "searchData")
public void searchTest(String keyword) {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
System.out.println(
"Searching: " + keyword +
" | Thread: " +
Thread.currentThread().getId()
);
} finally {
driver.quit();
}
}
In production frameworks, driver lifecycle management should normally be centralized through a Driver Factory or similar framework component.
20. Cross-Browser Parallel Testing
Cross-browser testing verifies application behavior on multiple browsers. Parallel execution allows those browser sessions to run concurrently.
Cross Browser Suite
|
+------------+------------+
| | |
v v v
Chrome Firefox Edge
| | |
v v v
Test 1 Test 1 Test 1
| | |
+------------+------------+
|
v
Report
This approach is particularly useful for regression testing where the same workflow needs to be validated on several supported browsers.
21. Cross-Browser XML Example
<suite name="CrossBrowserSuite"
parallel="tests"
thread-count="3">
<test name="Chrome">
<parameter name="browser" value="chrome"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
<test name="Firefox">
<parameter name="browser" value="firefox"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
<test name="Edge">
<parameter name="browser" value="edge"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
22. Combining @Parameters with Parallel Testing
TestNG XML parameters can be combined with parallel execution to provide different configuration values to different TestNG test blocks.
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class BrowserTest {
@Parameters("browser")
@Test
public void browserTest(String browser) {
System.out.println(
"Browser: " + browser +
" | Thread: " +
Thread.currentThread().getId()
);
}
}
Each <test> block can provide its own browser parameter while TestNG executes the blocks concurrently.
23. Parallel Testing with Page Object Model
Parallel execution works well with the Page Object Model when page objects are designed to use the WebDriver instance belonging to the current test execution.
Thread 1
|
+-- Driver 1
|
+-- LoginPage 1
|
+-- Login Test 1
Thread 2
|
+-- Driver 2
|
+-- LoginPage 2
|
+-- Login Test 2
Page objects should not unexpectedly share mutable browser state between concurrent test executions.
24. Parallel POM Example
public class LoginPage {
private WebDriver driver;
private By username = By.id("username");
private By password = By.id("password");
private By loginButton = By.id("loginButton");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
public void login(String user, String pass) {
driver.findElement(username).sendKeys(user);
driver.findElement(password).sendKeys(pass);
driver.findElement(loginButton).click();
}
}
The WebDriver is supplied to the page object so that the page object operates on the appropriate browser session.
25. Parallel Testing with TestNG Groups
TestNG groups can organize related tests. Groups can be combined with suite execution strategies, although test dependencies and shared state must be considered before enabling concurrency.
import org.testng.annotations.Test;
public class GroupTests {
@Test(groups = "smoke")
public void loginTest() {
System.out.println("Login");
}
@Test(groups = "smoke")
public void searchTest() {
System.out.println("Search");
}
@Test(groups = "regression")
public void checkoutTest() {
System.out.println("Checkout");
}
}
26. Parallel Testing and Test Dependencies
Parallel execution can become complicated when one test depends on another test.
Test A
|
v
Test B
|
v
Test C
If Test B requires Test A to finish first, blindly running both in parallel can create incorrect behavior. Tests with dependencies should be designed according to their dependency relationships.
Independent tests are generally easier candidates for parallel execution.
27. Independent vs Dependent Tests
| Test Type | Parallel Suitability | Reason |
| Independent Login Test | Suitable | Does not depend on another test |
| Independent Search Test | Suitable | Can use its own session |
| Independent Product Test | Suitable | Can execute separately |
| Checkout requiring previous cart state | Requires design consideration | May depend on state created elsewhere |
| Tests sharing one WebDriver | Unsafe without proper synchronization | Browser commands can interfere |
28. Shared State Problem
Shared state occurs when multiple parallel tests access or modify the same mutable resource.
Examples include:
- Shared WebDriver instance.
- Shared static variables.
- Shared test accounts.
- Shared files.
- Shared database records.
- Shared application sessions.
- Shared mutable page objects.
Parallel test design should minimize unintended shared state.
29. Thread Safety
Thread safety means that a component behaves correctly when accessed concurrently by multiple threads.
Important Selenium framework components that should be reviewed for thread safety include:
- WebDriver management.
- Page object instances.
- Test data objects.
- Reporting utilities.
- Logging utilities.
- Database utilities.
- Configuration objects.
- Temporary file handling.
30. WebDriver Thread Safety
WebDriver sessions should generally be isolated between concurrent test executions.
Incorrect Design:
Thread 1 ----+
|
Thread 2 ----+----> Shared WebDriver
|
Thread 3 ----+
Potential Result:
Tests interfere with one another.
Preferred Design:
Thread 1 ----> Driver 1
Thread 2 ----> Driver 2
Thread 3 ----> Driver 3
31. Driver Factory for Parallel Execution
A Driver Factory centralizes browser creation and can be designed to provide thread-specific WebDriver instances.
public class DriverFactory {
public static WebDriver createDriver(String browser) {
if (browser.equalsIgnoreCase("chrome")) {
return new ChromeDriver();
}
if (browser.equalsIgnoreCase("firefox")) {
return new FirefoxDriver();
}
if (browser.equalsIgnoreCase("edge")) {
return new EdgeDriver();
}
throw new IllegalArgumentException(
"Unsupported browser: " + browser
);
}
}
A production framework can extend this design with ThreadLocal storage, configuration management, remote execution, and driver lifecycle handling.
32. Selenium Grid and Parallel Testing
Selenium Grid allows WebDriver tests to execute on remote browser environments. It is commonly used when parallel execution needs to be distributed across multiple machines, containers, or browser nodes.
Test Suite
|
v
Selenium Grid
|
+------------+------------+
| | |
v v v
Node 1 Node 2 Node 3
Chrome Firefox Edge
| | |
v v v
Test A Test B Test C
33. RemoteWebDriver with Parallel Testing
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.net.MalformedURLException;
import java.net.URI;
public class RemoteDriverExample {
public WebDriver createDriver()
throws MalformedURLException {
ChromeOptions options = new ChromeOptions();
return new RemoteWebDriver(
URI.create("http://localhost:4444").toURL(),
options
);
}
}
The exact Grid infrastructure and remote URL depend on the environment in which the Selenium Grid is deployed.
34. Parallel Testing in CI/CD
Parallel testing is particularly useful in continuous integration and continuous delivery pipelines. A large regression suite can be distributed across multiple execution threads or environments.
Developer Commit
|
v
CI/CD Pipeline
|
v
Build
|
v
TestNG
|
v
Parallel Execution
|
+---+---+---+
| | | |
v v v v
Test Test Test Test
| | | |
+---+---+---+
|
v
Reports
35. Parallel Testing with Maven
Parallel TestNG tests can be executed through Maven when the project is configured with the appropriate testing dependencies and suite configuration.
mvn test
The Maven build can invoke the TestNG suite, which then manages the configured parallel execution.
36. Parallel Testing and Test Reports
When tests execute concurrently, the reporting system should correctly associate each result with its test, data set, browser, and execution context.
Parallel Execution
|
+---- Login - Chrome - PASS
|
+---- Login - Firefox - PASS
|
+---- Search - Chrome - FAIL
|
+---- Checkout - Edge - PASS
|
v
Test Report
Reports should make it easy to identify failures without relying on execution order.
37. Logging in Parallel Tests
Logging becomes especially important during parallel execution because messages from different threads can appear interleaved.
Thread 12 | Login Test | Chrome
Thread 13 | Search Test | Firefox
Thread 14 | Checkout Test | Edge
Thread 12 | Login Test | PASS
Thread 13 | Search Test | FAIL
Useful log information can include thread ID, test name, browser, environment, test data identifier, and execution status.
38. Parallel Testing with Screenshots
When a parallel test fails, screenshots should be associated with the correct test execution. Screenshot filenames should be unique to avoid one test overwriting another test's screenshot.
screenshots/
|-- LoginTest_Chrome_Thread12.png
|-- LoginTest_Firefox_Thread13.png
|-- SearchTest_Chrome_Thread14.png
39. Unique File Names in Parallel Execution
Parallel tests may generate files simultaneously. A shared static filename can cause conflicts.
A safer approach is to include identifiers such as test name, timestamp, browser, or thread ID.
String fileName =
testName + "_" +
browser + "_" +
Thread.currentThread().getId() +
".png";
40. Parallel Testing with Data Providers and ThreadLocal
A common architecture combines parallel Data Providers with ThreadLocal WebDriver management.
@DataProvider(
name = "users",
parallel = true
)
public Object[][] users() {
return new Object[][] {
{"user1"},
{"user2"},
{"user3"}
};
}
@Test(dataProvider = "users")
public void loginTest(String username) {
WebDriver driver = DriverFactory.getDriver();
driver.get("https://example.com/login");
System.out.println(
"User: " + username +
" | Thread: " +
Thread.currentThread().getId()
);
}
The exact DriverFactory implementation should ensure that the current thread receives the correct driver.
41. Parallel Testing with Multiple Browsers
A scalable automation framework can combine browser parameters, TestNG parallel execution, and a Driver Factory.
TestNG XML
|
+---- Chrome
|
+---- Firefox
|
+---- Edge
|
v
Driver Factory
|
v
Thread-specific Driver
|
v
Test Case
42. Parallel Testing Architecture
TestNG Suite
|
v
Parallel Scheduler
|
+--------------+--------------+
| | |
v v v
Thread 1 Thread 2 Thread 3
| | |
v v v
Driver 1 Driver 2 Driver 3
| | |
v v v
Page Obj 1 Page Obj 2 Page Obj 3
| | |
+--------------+--------------+
|
v
Application
|
v
Results
43. Parallel Testing and Test Data Isolation
Test data should also be isolated when tests execute concurrently. For example, two tests should not unintentionally modify the same user account at the same time.
Possible strategies include:
- Dedicated test users.
- Unique test records.
- Generated test data.
- Data cleanup after execution.
- Environment-specific test data.
- Thread-specific test-data identifiers.
44. Parallel Testing and Database Operations
Database access can also become a concurrency concern. Parallel tests that update the same database records can interfere with one another.
Framework designers should consider:
- Unique records per test.
- Transaction handling.
- Database cleanup.
- Connection management.
- Synchronization where genuinely required.
- Environment isolation.
45. Parallel Testing and Synchronization
Synchronization should be used carefully. The goal of parallel execution is concurrency, so excessive synchronization can eliminate the performance benefit.
Synchronization may be appropriate when multiple tests must access a genuinely shared resource that cannot be safely isolated.
46. Common Problems in Parallel Testing
- Shared WebDriver instances.
- Static mutable variables.
- Shared test accounts.
- Duplicate screenshot names.
- Shared temporary files.
- Race conditions.
- Unstable test dependencies.
- Incorrect ThreadLocal cleanup.
- Non-thread-safe reporting utilities.
- Tests depending on execution order.
- Database record conflicts.
- Insufficient execution infrastructure.
47. Race Conditions
A race condition occurs when the result depends on the timing or ordering of concurrent operations.
Thread 1
|
+---- Read Record
|
+---- Update Record
|
v
Thread 2
|
+---- Read Same Record
|
+---- Update Same Record
Such situations can produce inconsistent results if the shared resource is not properly isolated or synchronized.
48. Deadlocks
A deadlock can occur when concurrent operations wait indefinitely for resources held by each other. Good parallel framework design should avoid unnecessary locking and circular resource dependencies.
49. Flaky Tests in Parallel Execution
A test that passes individually but fails intermittently during parallel execution may indicate a concurrency, isolation, timing, or shared-state problem.
Common causes include:
- Shared WebDriver.
- Shared test data.
- Race conditions.
- Static variables.
- Incorrect cleanup.
- Shared files.
- Application-side concurrency limitations.
50. How to Debug Parallel Tests
- Record the thread ID.
- Record the test name.
- Record the browser and environment.
- Record a unique test-data identifier.
- Capture screenshots on failure.
- Store logs separately where practical.
- Check whether WebDriver instances are isolated.
- Check static and shared variables.
- Run the failing test sequentially for comparison.
- Reduce the thread count to reproduce the issue.
51. Sequential vs Parallel Debugging
A useful troubleshooting technique is to compare the same suite under sequential and parallel execution.
Sequential Run
|
v
Tests Pass
|
v
Parallel Run
|
v
Some Tests Fail
|
v
Investigate
|
+-- Shared State?
+-- WebDriver?
+-- Test Data?
+-- File Conflict?
+-- Race Condition?
52. Choosing the Right Parallel Strategy
| Requirement | Possible Strategy |
| Run browser configurations concurrently | parallel="tests" |
| Run independent classes concurrently | parallel="classes" |
| Run independent methods concurrently | parallel="methods" |
| Run Data Provider rows concurrently | DataProvider parallel=true |
| Run tests on remote machines | Selenium Grid |
53. When Should Parallel Testing Be Used?
Parallel testing is particularly useful when:
- The test suite is large.
- Tests are independent.
- Multiple browsers need to be tested.
- CI/CD execution time needs to be managed efficiently.
- Sufficient execution infrastructure is available.
- WebDriver and test data are properly isolated.
54. When Should Parallel Testing Be Avoided or Limited?
Parallelism may need to be limited when tests heavily depend on one another or when the environment cannot safely support concurrent execution.
- Tests depend strongly on execution order.
- Tests share mutable application state.
- The application environment cannot handle concurrent sessions.
- Test data cannot be isolated.
- Framework components are not thread-safe.
- Infrastructure resources are insufficient.
55. Parallel Testing and Performance
Parallel testing can reduce wall-clock execution time, but increasing the thread count indefinitely does not guarantee proportional improvement. CPU, memory, browser resources, network capacity, application capacity, and test dependencies can become bottlenecks.
More Threads
|
v
More Concurrent Tests
|
+---- CPU Usage
+---- Memory Usage
+---- Browser Sessions
+---- Network Usage
+---- Application Load
|
v
Potential Bottleneck
The appropriate thread count should therefore be determined based on the framework and execution environment.
56. Parallel Testing and Resource Management
Every parallel browser session consumes resources. A framework should clean up browser sessions and temporary resources after each test.
Test Starts
|
v
Create Driver
|
v
Execute Test
|
v
Capture Result
|
v
Quit Driver
|
v
Release Thread-specific Resources
57. Parallel Testing with Setup and Teardown
TestNG configuration methods should be designed with parallel execution in mind.
@BeforeMethod
public void setup() {
// Create isolated test resources
}
@Test
public void test() {
// Execute test
}
@AfterMethod
public void tearDown() {
// Release isolated resources
}
Setup and teardown should not accidentally overwrite resources belonging to another concurrent test.
58. Complete Practical Parallel Selenium Example
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ParallelLoginTest {
private ThreadLocal<WebDriver> driver =
new ThreadLocal<>();
@BeforeMethod
public void setup() {
driver.set(new ChromeDriver());
driver.get().manage().window().maximize();
}
@DataProvider(
name = "users",
parallel = true
)
public Object[][] users() {
return new Object[][] {
{"user1", "pass1"},
{"user2", "pass2"},
{"user3", "pass3"}
};
}
@Test(dataProvider = "users")
public void loginTest(
String username,
String password) {
WebDriver webDriver = driver.get();
webDriver.get("https://example.com/login");
System.out.println(
"Username: " + username +
" | Thread: " +
Thread.currentThread().getId()
);
// Login steps can be performed here.
}
@AfterMethod
public void tearDown() {
WebDriver webDriver = driver.get();
if (webDriver != null) {
webDriver.quit();
driver.remove();
}
}
}
This example demonstrates the basic concept of combining parallel Data Provider execution with thread-specific WebDriver storage. In a production framework, DriverFactory, configuration, reporting, waits, page objects, and error handling would normally be separated into reusable components.
59. Practical Project Structure
src
|-- test
|-- java
|-- tests
| |-- LoginTest.java
| |-- SearchTest.java
| |-- CheckoutTest.java
|
|-- pages
| |-- LoginPage.java
| |-- SearchPage.java
| |-- CheckoutPage.java
|
|-- factory
| |-- DriverFactory.java
|
|-- data
| |-- LoginDataProvider.java
| |-- SearchDataProvider.java
|
|-- utilities
|-- ConfigReader.java
|-- ScreenshotUtility.java
|-- ReportUtility.java
|-- WaitUtility.java
|
|-- resources
|-- config.properties
|-- testng.xml
60. Real-World Parallel Testing Architecture
TestNG Suite
|
v
Parallel Scheduler
|
+----------------+----------------+
| | |
v v v
Thread 1 Thread 2 Thread 3
| | |
v v v
Driver Factory Driver Factory Driver Factory
| | |
v v v
Chrome Session Firefox Session Edge Session
| | |
+----------------+----------------+
|
v
Page Objects
|
v
Application
|
v
Assertions
|
v
Reports + Logs
61. Advantages of Parallel Testing
- Reduced Execution Time: Multiple independent tests can execute concurrently.
- Better Regression Efficiency: Large regression suites can complete more quickly.
- Cross-Browser Coverage: Different browser sessions can be executed concurrently.
- CI/CD Support: Automated pipelines can execute large test suites more efficiently.
- Resource Utilization: Available test infrastructure can support multiple concurrent sessions.
- Scalability: Test execution can be expanded across multiple workers or Grid nodes.
- Faster Feedback: Teams can receive results from multiple independent tests without waiting for complete sequential execution.
62. Limitations of Parallel Testing
- Requires more computing resources.
- Framework design becomes more complex.
- Thread safety becomes important.
- Shared state can create failures.
- Debugging can become more difficult.
- Test data may require additional isolation.
- Reporting and logging need concurrency-aware design.
- Application environments may not support unlimited concurrent sessions.
- Browser sessions consume additional memory and CPU.
63. Common Mistakes in Parallel Testing
- Using one static WebDriver for all tests.
- Sharing mutable page objects between threads.
- Using the same test account simultaneously without considering application behavior.
- Using duplicate screenshot filenames.
- Creating static mutable test data.
- Forgetting to quit WebDriver instances.
- Not removing ThreadLocal values after execution.
- Using parallel execution on dependent tests.
- Assuming that a higher thread count is always better.
- Ignoring application and infrastructure capacity.
- Not including thread information in logs.
- Using non-thread-safe reporting utilities.
64. Best Practices for Parallel Testing
- Use one isolated WebDriver instance per concurrent test execution.
- Consider ThreadLocal for thread-specific WebDriver management.
- Keep tests independent whenever practical.
- Use unique test data for concurrent executions.
- Avoid unnecessary static mutable variables.
- Use a centralized Driver Factory.
- Keep page objects scoped to the appropriate test execution.
- Use unique screenshot and log filenames.
- Include thread ID, browser, and test name in diagnostic logs.
- Clean up WebDriver and ThreadLocal resources.
- Choose thread counts based on actual infrastructure capacity.
- Use Selenium Grid when distributed execution is required.
- Do not parallelize tests simply for the sake of parallelization.
- Validate the suite sequentially and then introduce parallelism gradually.
- Monitor flaky failures after enabling concurrency.
65. Parallel Testing vs Distributed Testing
Parallel testing and distributed testing are related but not identical concepts.
| Concept | Description |
| Parallel Testing | Multiple test executions run concurrently. |
| Distributed Testing | Test execution is distributed across multiple machines, containers, or nodes. |
| Selenium Grid | Can provide infrastructure for distributed browser execution. |
| Thread Pool | Can provide concurrency within an execution environment. |
66. Parallel Testing and Selenium Grid
A large enterprise automation framework may combine TestNG parallel execution with Selenium Grid.
CI/CD Server
|
v
TestNG
|
v
Parallel Threads
|
v
Selenium Grid
|
+---+---+---+
| | | |
v v v v
Node Node Node Node
| | | |
Chrome Firefox Edge Chrome
| | | |
+----+----+----+
|
v
Test Results
67. Parallel Testing Checklist
- Are the tests independent?
- Does each test have an isolated WebDriver?
- Is the test data safe for concurrent execution?
- Are static mutable variables avoided?
- Are screenshots uniquely named?
- Are logs associated with the correct test?
- Is ThreadLocal cleaned up correctly?
- Is the configured thread count appropriate?
- Can the application handle concurrent sessions?
- Can the infrastructure handle the browser load?
- Are reports able to distinguish concurrent executions?
- Have flaky tests been investigated?
68. Interview Questions on Parallel Testing
1. What is parallel testing?
Parallel testing is the execution of multiple independent test cases or test invocations concurrently.
2. Why is parallel testing used in Selenium?
It is commonly used to reduce execution time and support concurrent browser and regression testing.
3. How can TestNG execute tests in parallel?
TestNG supports parallel execution through suite configuration such as parallel="tests", parallel="classes", parallel="methods", and Data Provider parallel execution.
4. What is thread-count in TestNG?
Thread-count specifies the maximum number of threads available for the configured parallel execution.
5. What is parallel="tests"?
It allows eligible TestNG <test> blocks to execute concurrently.
6. What is parallel="classes"?
It allows eligible test classes to execute concurrently.
7. What is parallel="methods"?
It allows eligible test methods to execute concurrently.
8. Can Data Providers run in parallel?
Yes. A Data Provider can be configured using parallel = true.
9. Why should WebDriver not be shared between parallel tests?
Because multiple concurrent tests can send commands to the same browser session and interfere with one another.
10. What is ThreadLocal?
ThreadLocal provides thread-specific storage, making it useful for maintaining a separate WebDriver reference for each executing thread.
11. What is Selenium Grid's role in parallel testing?
Selenium Grid can provide remote browser infrastructure across multiple nodes, allowing concurrent browser sessions to run across distributed environments.
12. What is a race condition?
A race condition occurs when concurrent operations access shared resources and the result depends on their timing or ordering.
13. What is a common cause of flaky parallel tests?
Shared WebDriver instances, shared test data, race conditions, static mutable state, and improper cleanup are common causes.
14. Should all tests be executed in parallel?
No. Tests should be evaluated for independence, thread safety, data isolation, and application capacity before parallel execution is enabled.
15. How can screenshots be handled in parallel tests?
Screenshot filenames should be unique and should include useful identifiers such as test name, browser, timestamp, or thread ID.
16. Can parallel testing be used with Page Object Model?
Yes. Page objects should be created and used in a way that preserves WebDriver and test-state isolation.
17. What happens if two parallel tests use the same database record?
They may interfere with each other and produce inconsistent results. Test data should be isolated whenever practical.
18. Does increasing thread-count always improve performance?
No. CPU, memory, browser, network, application, and infrastructure limitations can become bottlenecks.
19. What is the difference between parallel and distributed testing?
Parallel testing describes concurrent execution, while distributed testing describes execution spread across multiple machines, nodes, containers, or environments.
20. What is the most important principle of Selenium parallel testing?
Concurrent tests should have isolated browser sessions and test state, with framework components designed to be thread-safe.
69. Quick Reference Table
| Concept | Description |
| Parallel Testing | Concurrent execution of independent tests |
| parallel="tests" | Runs TestNG test blocks concurrently |
| parallel="classes" | Runs test classes concurrently |
| parallel="methods" | Runs test methods concurrently |
| thread-count | Controls maximum parallel thread capacity |
| DataProvider parallel | Allows Data Provider invocations to execute concurrently |
| ThreadLocal | Provides thread-specific storage |
| Driver Factory | Centralizes WebDriver creation and management |
| Selenium Grid | Supports remote and distributed browser execution |
| Thread Safety | Ensures components behave correctly under concurrent access |
| Test Isolation | Prevents concurrent tests from interfering with one another |
70. Learning Roadmap for Parallel Testing
- Understand Selenium WebDriver basics.
- Learn TestNG fundamentals.
- Understand TestNG suites and test blocks.
- Learn TestNG parallel execution modes.
- Understand thread-count.
- Practice parallel="tests".
- Practice parallel="classes".
- Practice parallel="methods".
- Learn Data Provider parallel execution.
- Understand WebDriver isolation.
- Learn ThreadLocal WebDriver management.
- Build a Driver Factory.
- Combine parallel execution with Page Object Model.
- Learn cross-browser parallel testing.
- Learn Selenium Grid.
- Implement thread-safe reporting and logging.
- Practice test-data isolation.
- Integrate parallel tests with Maven.
- Integrate parallel tests with CI/CD.
- Build a scalable parallel Selenium automation framework.
71. Practical Exercises
- Create three independent TestNG test methods and execute them in parallel.
- Create a TestNG XML suite using parallel="tests".
- Execute three test classes using parallel="classes".
- Execute independent test methods using parallel="methods".
- Create a Data Provider with five users and execute it in parallel.
- Create a cross-browser suite for Chrome, Firefox, and Edge.
- Implement ThreadLocal WebDriver management.
- Create a reusable Driver Factory.
- Combine ThreadLocal WebDriver with Page Object Model.
- Capture unique screenshots from parallel tests.
- Add thread IDs to framework logs.
- Execute tests through Selenium Grid.
- Integrate the parallel suite with Maven.
- Execute the parallel suite in a CI/CD environment.
72. Summary
Parallel Testing is an important technique for modern Selenium automation frameworks. It allows multiple independent test executions to run concurrently instead of waiting for each test to complete sequentially.
TestNG provides several mechanisms for parallel execution, including parallel="tests", parallel="classes", parallel="methods", and parallel Data Providers.
For Selenium automation, proper WebDriver isolation is one of the most important requirements. ThreadLocal, Driver Factory patterns, isolated page objects, independent test data, and appropriate cleanup can help create a reliable parallel framework.
Parallel testing can also be combined with Selenium Grid, Page Object Model, Maven, CI/CD, reporting, logging, and Data Providers to create a scalable automation architecture.
The goal should not simply be to maximize the number of threads. The framework should use a concurrency level that provides efficient execution while maintaining test reliability, isolation, and reproducibility.
73. Course Resources
Learn more about Selenium automation and professional testing concepts:
Final Takeaway: Parallel Testing helps Selenium automation frameworks execute independent tests concurrently, reduce overall execution time, and support cross-browser and large-scale regression testing. Reliable parallel automation depends on isolated WebDriver sessions, thread-safe framework components, independent test data, proper resource cleanup, and carefully selected execution strategies.