In previous post, we learnt How a static WebDriver reference created problems in parallel execution. We will see solution of those problems in this post.
Please note I am exclusively using a static WebDriver reference but similar solution will be applicable for any static reference.
Solution I have already discussed in my previous post. We need to use ThreadLocal so that each thread will have their own reference to class variables including static class variables. Read more about ThreadLocal at my blog here.
Let’s declare a static WebDriver as ThreadLocal. I have created simple methods to set, get and remove driver.
Class WebDriverFactoryStaticThreadLocal :-
package SolvingParallelRunProblemWithStaticWebDriverUsingThreadLocal; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import io.github.bonigarcia.wdm.WebDriverManager; public class WebDriverFactoryStaticThreadLocal { private static ThreadLocaldriver = new ThreadLocal (); public static void setDriver() { WebDriverManager.chromedriver().setup(); driver.set(new ChromeDriver()); } public static WebDriver getDriver() { return driver.get(); } public static void closeBrowser() { driver.get().close(); driver.remove(); } }
Little changes to TestNG test classes to use driver instance using getter method and calling close method from WebDriverFactoryStaticThreadLocal class.
Class TestOneWithStaticWebDriver
package SolvingParallelRunProblemWithStaticWebDriverUsingThreadLocal; import java.lang.reflect.Method; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestOneWithStaticWebDriver { @BeforeClass public void setUp() { WebDriverFactoryStaticThreadLocal.setDriver(); System.out.println("Browser setup by Thread "+Thread.currentThread().getId()+" and Driver reference is : "+WebDriverFactoryStaticThreadLocal.getDriver()); } @Test public void GoogleTest(Method m) throws InterruptedException { System.out.println(m.getName()+" of class TestOneWithStaticWebDriver Executed by Thread "+Thread.currentThread().getId()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().get("https://www.google.com/"); Thread.sleep(15000); System.out.println("Title printed by Thread "+Thread.currentThread().getId()+" - "+WebDriverFactoryStaticThreadLocal.getDriver().getTitle()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().manage().deleteAllCookies(); } @Test public void FacebookTest(Method m) throws InterruptedException { System.out.println(m.getName()+" of class TestOneWithStaticWebDriver Executed by Thread "+Thread.currentThread().getId()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().get("https://www.facebook.com/"); Thread.sleep(15000); System.out.println("Title printed by Thread "+Thread.currentThread().getId()+" - "+WebDriverFactoryStaticThreadLocal.getDriver().getTitle()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().manage().deleteAllCookies(); } @AfterClass public void tearDown() { System.out.println("Browser closed by Thread "+Thread.currentThread().getId() + " and Closing driver reference is :"+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.closeBrowser(); } }
Class TestTwoWithStaticWebDriver :-
package SolvingParallelRunProblemWithStaticWebDriverUsingThreadLocal; import java.lang.reflect.Method; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestTwoWithStaticWebDriver { @BeforeClass public void setUp() throws InterruptedException { WebDriverFactoryStaticThreadLocal.setDriver(); System.out.println("Browser setup by Thread "+Thread.currentThread().getId()+" and Driver reference is : "+WebDriverFactoryStaticThreadLocal.getDriver()); } @Test public void FlipkartTest(Method m) throws InterruptedException { System.out.println(m.getName()+" of class TestOneWithStaticWebDriver Executed by Thread "+Thread.currentThread().getId()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().get("https://www.flipkart.com/"); Thread.sleep(15000); System.out.println("Title printed by Thread "+Thread.currentThread().getId()+" - "+WebDriverFactoryStaticThreadLocal.getDriver().getTitle()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().manage().deleteAllCookies(); } @Test public void MyntraTest(Method m) throws InterruptedException { System.out.println(m.getName()+" of class TestOneWithStaticWebDriver Executed by Thread "+Thread.currentThread().getId()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().get("https://www.myntra.com/"); Thread.sleep(15000); System.out.println("Title printed by Thread "+Thread.currentThread().getId()+" - "+WebDriverFactoryStaticThreadLocal.getDriver().getTitle()+" on driver reference "+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.getDriver().manage().deleteAllCookies(); } @AfterClass public void tearDown() { System.out.println("Browser closed by Thread "+Thread.currentThread().getId() + " and Closing driver reference is :"+WebDriverFactoryStaticThreadLocal.getDriver()); WebDriverFactoryStaticThreadLocal.closeBrowser(); } }
Let’s execute TestNG classes in parallel using TestNG xml as below:-
Output:-
Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 10510 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 22228 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser setup by Thread 12 and Driver reference is : ChromeDriver: chrome on WINDOWS (cb5584647d45d743f09ac3d56cc7d5eb) FlipkartTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference ChromeDriver: chrome on WINDOWS (cb5584647d45d743f09ac3d56cc7d5eb) Browser setup by Thread 11 and Driver reference is : ChromeDriver: chrome on WINDOWS (688aef6ce3b1d097ccb472605a11cda1) FacebookTest of class TestOneWithStaticWebDriver Executed by Thread 11 on driver reference ChromeDriver: chrome on WINDOWS (688aef6ce3b1d097ccb472605a11cda1) Title printed by Thread 12 - Online Shopping Site for Mobiles, Electronics, Furniture, Grocery, Lifestyle, Books & More. Best Offers! on driver reference ChromeDriver: chrome on WINDOWS (cb5584647d45d743f09ac3d56cc7d5eb) MyntraTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference ChromeDriver: chrome on WINDOWS (cb5584647d45d743f09ac3d56cc7d5eb) Title printed by Thread 11 - Facebook – log in or sign up on driver reference ChromeDriver: chrome on WINDOWS (688aef6ce3b1d097ccb472605a11cda1) GoogleTest of class TestOneWithStaticWebDriver Executed by Thread 11 on driver reference ChromeDriver: chrome on WINDOWS (688aef6ce3b1d097ccb472605a11cda1) Title printed by Thread 12 - Online Shopping for Women, Men, Kids Fashion & Lifestyle - Myntra on driver reference ChromeDriver: chrome on WINDOWS (cb5584647d45d743f09ac3d56cc7d5eb) Title printed by Thread 11 - Google on driver reference ChromeDriver: chrome on WINDOWS (688aef6ce3b1d097ccb472605a11cda1) Browser closed by Thread 12 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (cb5584647d45d743f09ac3d56cc7d5eb) Browser closed by Thread 11 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (688aef6ce3b1d097ccb472605a11cda1) =============================================== Suite Total tests run: 4, Passes: 4, Failures: 0, Skips: 0 ===============================================
Observe output and find how driver reference were kept separately for both threads and how ThreadLocal helped in that.
Let’s dig further little more.
Above we ran TestNG class in parallel. What will happen if we run @Test methods in parallel.
Let’s run by changing parallel attribute as below:-
Output:-
Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 8922 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser setup by Thread 11 and Driver reference is : ChromeDriver: chrome on WINDOWS (09b76840ac98cadec934d88834e1d10f) FacebookTest of class TestOneWithStaticWebDriver Executed by Thread 11 on driver reference ChromeDriver: chrome on WINDOWS (09b76840ac98cadec934d88834e1d10f) GoogleTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference null Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 21202 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser setup by Thread 12 and Driver reference is : ChromeDriver: chrome on WINDOWS (d2c3ccddb813d65c161e7ddef78c69e1) FlipkartTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference ChromeDriver: chrome on WINDOWS (d2c3ccddb813d65c161e7ddef78c69e1) Title printed by Thread 11 - Facebook – log in or sign up on driver reference ChromeDriver: chrome on WINDOWS (09b76840ac98cadec934d88834e1d10f) Browser closed by Thread 11 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (09b76840ac98cadec934d88834e1d10f) Title printed by Thread 12 - Online Shopping Site for Mobiles, Electronics, Furniture, Grocery, Lifestyle, Books & More. Best Offers! on driver reference ChromeDriver: chrome on WINDOWS (d2c3ccddb813d65c161e7ddef78c69e1) MyntraTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference ChromeDriver: chrome on WINDOWS (d2c3ccddb813d65c161e7ddef78c69e1) Title printed by Thread 12 - Online Shopping for Women, Men, Kids Fashion & Lifestyle - Myntra on driver reference ChromeDriver: chrome on WINDOWS (d2c3ccddb813d65c161e7ddef78c69e1) Browser closed by Thread 12 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (d2c3ccddb813d65c161e7ddef78c69e1) =============================================== Suite Total tests run: 4, Passes: 3, Failures: 1, Skips: 0 ===============================================
Again something unexpected happen and one test could not find a browser to execute on. Reason behind this is that @BeforeClass and @AfterClass will not be executed for each @Test annotated methods if we run them in parallel. We were expecting that since we are running @Test methods in parallel, @BeforeClass and @AfterClass for each test methods will be called but it does not work in that way. You may ask what will happen if we set thread count as 4 which is equal to test method. Try that as well. You will see two threads will have browser to execute test but another two threads will have null driver reference.
Output:-
Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 23221 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 32111 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser setup by Thread 11 and Driver reference is : ChromeDriver: chrome on WINDOWS (583d8dfe75d4a363ad23ab034070667e) FacebookTest of class TestOneWithStaticWebDriver Executed by Thread 11 on driver reference ChromeDriver: chrome on WINDOWS (583d8dfe75d4a363ad23ab034070667e) GoogleTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference null Browser setup by Thread 13 and Driver reference is : ChromeDriver: chrome on WINDOWS (043c2560edb033c8206eb14691ed64d4) FlipkartTest of class TestOneWithStaticWebDriver Executed by Thread 13 on driver reference ChromeDriver: chrome on WINDOWS (043c2560edb033c8206eb14691ed64d4) MyntraTest of class TestOneWithStaticWebDriver Executed by Thread 14 on driver reference null Title printed by Thread 13 - Online Shopping Site for Mobiles, Electronics, Furniture, Grocery, Lifestyle, Books & More. Best Offers! on driver reference ChromeDriver: chrome on WINDOWS (043c2560edb033c8206eb14691ed64d4) Browser closed by Thread 13 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (043c2560edb033c8206eb14691ed64d4) Title printed by Thread 11 - Facebook – log in or sign up on driver reference ChromeDriver: chrome on WINDOWS (583d8dfe75d4a363ad23ab034070667e) Browser closed by Thread 11 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (583d8dfe75d4a363ad23ab034070667e) =============================================== Suite Total tests run: 4, Passes: 2, Failures: 2, Skips: 0 ===============================================
Since tests execution requires browsers, so we need to change BeforeClass and AfterClass to BeforeMethod and AfterMethod. Change it and run.
Output:-
Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 8979 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 40461 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser setup by Thread 12 and Driver reference is : ChromeDriver: chrome on WINDOWS (973c57935ea39165f83a18ae70792aef) GoogleTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference ChromeDriver: chrome on WINDOWS (973c57935ea39165f83a18ae70792aef) Browser setup by Thread 11 and Driver reference is : ChromeDriver: chrome on WINDOWS (fb9c461922b6272fcf813d43fd66edd0) FacebookTest of class TestOneWithStaticWebDriver Executed by Thread 11 on driver reference ChromeDriver: chrome on WINDOWS (fb9c461922b6272fcf813d43fd66edd0) Title printed by Thread 12 - Google on driver reference ChromeDriver: chrome on WINDOWS (973c57935ea39165f83a18ae70792aef) Browser closed by Thread 12 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (973c57935ea39165f83a18ae70792aef) Title printed by Thread 11 - Facebook – log in or sign up on driver reference ChromeDriver: chrome on WINDOWS (fb9c461922b6272fcf813d43fd66edd0) Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 31716 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser closed by Thread 11 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (fb9c461922b6272fcf813d43fd66edd0) Starting ChromeDriver 80.0.3987.106 (f68069574609230cf9b635cd784cfb1bf81bb53a-refs/branch-heads/3987@{#882}) on port 20172 Only local connections are allowed. Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code. Browser setup by Thread 12 and Driver reference is : ChromeDriver: chrome on WINDOWS (c4e227a725fa2209611bf4fb12eb1dfa) FlipkartTest of class TestOneWithStaticWebDriver Executed by Thread 12 on driver reference ChromeDriver: chrome on WINDOWS (c4e227a725fa2209611bf4fb12eb1dfa) Browser setup by Thread 11 and Driver reference is : ChromeDriver: chrome on WINDOWS (d67145a966ee60d0fae790b60efb60a4) MyntraTest of class TestOneWithStaticWebDriver Executed by Thread 11 on driver reference ChromeDriver: chrome on WINDOWS (d67145a966ee60d0fae790b60efb60a4) Title printed by Thread 12 - Online Shopping Site for Mobiles, Electronics, Furniture, Grocery, Lifestyle, Books & More. Best Offers! on driver reference ChromeDriver: chrome on WINDOWS (c4e227a725fa2209611bf4fb12eb1dfa) Browser closed by Thread 12 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (c4e227a725fa2209611bf4fb12eb1dfa) Title printed by Thread 11 - Online Shopping for Women, Men, Kids Fashion & Lifestyle - Myntra on driver reference ChromeDriver: chrome on WINDOWS (d67145a966ee60d0fae790b60efb60a4) Browser closed by Thread 11 and Closing driver reference is :ChromeDriver: chrome on WINDOWS (d67145a966ee60d0fae790b60efb60a4) =============================================== Suite Total tests run: 4, Passes: 4, Failures: 0, Skips: 0 ===============================================
You can download code form this repo.
If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning
You can find all Selenium related post here.
You can find all API manual and automation related posts here.
You can find frequently asked Java Programs here.
Hi Amod,
I am using docker selenium grid and running our script parallelly by test tag but 1 test case is getting failed. Can you please help me?
Here is the testng file-
Here is the driver launch code-
protected static ThreadLocal driver = new ThreadLocal();
public static void intializeRemoteBrowser(String browserType) throws MalformedURLException {
DesiredCapabilities cap = new DesiredCapabilities();
if (browserType.equalsIgnoreCase(“chrome”)) {
cap.setBrowserName(BrowserType.CHROME);
WebDriverManager.chromedriver().setup();
System.out.println(“########### TEST CASE EXECUTION STARTED ON ==>” + browserType+” : “+ Thread.currentThread().getId());
}
else if (browserType.equalsIgnoreCase(“firefox”)) {
cap.setBrowserName(BrowserType.FIREFOX);
WebDriverManager.firefoxdriver().setup();
System.out.println(“########### TEST CASE EXECUTION STARTED ON ==>” + browserType+” : “+ Thread.currentThread().getId());
}
public static WebDriver getDriver() {
return driver.get();
}
public static void closeBrowser() {
driver.get().close();
driver.remove();
System.out.println(“###############TEST CASES EXECUTION ENDED###############”+” : “+ Thread.currentThread().getId());
}
I donot have testng, how do I run tests parallel using junit. I have static webdriver
Hi Amod, can I use the same code in case of multiple browsers as well? My existing code has else if statements for different browsers.
Hi Amod can you explain regarding failure when it’s @BeforeClass @AfterClass Scenario with parallel = methods. Step by Step .
Hi Rajesh, what is your confusion?