Test parallelization in CI in Selenium Java - Build an Automation Script
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.time.Duration; public class ParallelLoginTest { private ThreadLocal<WebDriver> driver = new ThreadLocal<>(); @BeforeMethod public void setUp() { // Setup ChromeDriver for each thread System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); driver.set(new ChromeDriver()); } @Test(dataProvider = "loginData", threadPoolSize = 3) public void testLogin(String email, String password) { WebDriver webDriver = driver.get(); webDriver.get("https://example.com/login"); WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10)); WebElement emailField = wait.until(ExpectedConditions.elementToBeClickable(By.id("email"))); emailField.clear(); emailField.sendKeys(email); WebElement passwordField = webDriver.findElement(By.id("password")); passwordField.clear(); passwordField.sendKeys(password); WebElement loginButton = wait.until(ExpectedConditions.elementToBeClickable(By.id("loginBtn"))); loginButton.click(); // Wait for dashboard URL wait.until(ExpectedConditions.urlContains("/dashboard")); String currentUrl = webDriver.getCurrentUrl(); Assert.assertTrue(currentUrl.contains("/dashboard"), "User should be redirected to dashboard"); } @DataProvider(name = "loginData", parallel = true) public Object[][] loginData() { return new Object[][] { {"user1@example.com", "Password1!"}, {"user2@example.com", "Password2!"}, {"user3@example.com", "Password3!"} }; } @AfterMethod public void tearDown() { driver.get().quit(); driver.remove(); } }
This test class uses TestNG and Selenium WebDriver to run login tests in parallel.
We use ThreadLocal<WebDriver> to ensure each test thread has its own browser instance, avoiding interference.
The @DataProvider supplies three sets of login credentials and is marked parallel=true to enable parallel execution.
The @Test method uses explicit waits to ensure elements are ready before interacting, improving reliability.
Assertions check that after login, the URL contains '/dashboard', confirming successful login.
Finally, @BeforeMethod and @AfterMethod setup and clean up the WebDriver instances per test thread.
This setup is suitable for running in a CI environment configured to run TestNG tests in parallel.
Now add data-driven testing with 3 different user credentials to run in parallel
Practice
Solution
Step 1: Understand parallel test execution
Parallel execution means running multiple tests at the same time instead of one after another.Step 2: Identify the benefit in CI
Running tests simultaneously saves time, making the feedback faster in continuous integration.Final Answer:
It reduces the total test execution time by running tests simultaneously. -> Option CQuick Check:
Parallel tests = faster execution [OK]
- Thinking parallel means tests run in order
- Believing parallel increases test count
- Assuming parallel disables flaky tests
Solution
Step 1: Recall TestNG XML syntax for parallelism
The correct attribute to enable parallel execution is 'parallel' with values like 'methods', 'tests', or 'classes'.Step 2: Identify correct thread count attribute
The attribute 'thread-count' sets how many threads run in parallel.Final Answer:
<suite parallel="methods" thread-count="4"> -> Option BQuick Check:
parallel + thread-count = correct syntax [OK]
- Using non-existent attributes like runParallel
- Confusing thread-count with threads
- Using order="sequential" disables parallelism
<suite name="Suite" parallel="tests" thread-count="3"> <test name="Test1">...</test> <test name="Test2">...</test> <test name="Test3">...</test> <test name="Test4">...</test> </suite>
Solution
Step 1: Understand parallel="tests" meaning
Setting parallel="tests" means TestNG runs multiple <test> tags at the same time.Step 2: Check thread-count value
thread-count="3" limits the number of simultaneous threads to 3, so max 3 tests run together.Final Answer:
3 tests run simultaneously -> Option AQuick Check:
parallel=tests + thread-count=3 means 3 parallel tests [OK]
- Assuming all tests run at once ignoring thread-count
- Confusing parallel="methods" with parallel="tests"
- Thinking thread-count is ignored
parallel="methods" and thread-count="2". Your tests share a static WebDriver instance. What problem will most likely occur?Solution
Step 1: Understand parallel methods with shared static WebDriver
Parallel methods run at the same time, but sharing a static WebDriver means all tests use the same browser instance.Step 2: Identify concurrency issues
Sharing one WebDriver causes conflicts like commands overlapping, leading to test failures.Final Answer:
Tests will fail due to WebDriver conflicts from shared instance. -> Option AQuick Check:
Shared static WebDriver + parallel = conflicts [OK]
- Assuming shared WebDriver works fine in parallel
- Thinking parallel disables shared resource conflicts
- Believing TestNG creates separate WebDriver automatically
Solution
Step 1: Identify parallel="methods" for running all test methods in parallel
To run all methods in parallel, use parallel="methods" in the suite tag.Step 2: Set thread-count="6" to limit total threads
thread-count="6" limits the number of simultaneous threads to 6, matching the requirement.Step 3: Confirm classes are inside a single <test> tag
All classes are grouped under one <test> tag, so methods from all classes run in parallel within the thread limit.Final Answer:
<suite parallel="methods" thread-count="6"> -> Option DQuick Check:
parallel="methods" + thread-count="6" + single <test> [OK]
- Using parallel="classes" runs classes in parallel, not methods
- Using thread-count too high ignores limit
- Splitting classes into multiple tests changes parallel behavior
Ready to prove it?
Pass the test and this pattern moves unknown
