Parallel Execution using TestNG
For Parallel execution ,we will be working on 3 different components as below:
- A Factory class that will create WebDriver instances
- A Manager class that can be accessed to retrieve a WebDriver instance
- A TestNG listener that will be responsible for instantiating the WebDriver instance automatically
First we will create a Factory class which will create and return the desired webdriver object:
package execution.parallel;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.firefox.FirefoxDriver;import org.openqa.selenium.ie.InternetExplorerDriver;class LocalDriverFactory { static WebDriver createInstance(String browserName) { WebDriver driver = null; if (browserName.toLowerCase().contains("firefox")) { driver = new FirefoxDriver(); return driver; } if (browserName.toLowerCase().contains("internet")) { driver = new InternetExplorerDriver(); return driver; } if (browserName.toLowerCase().contains("chrome")) { driver = new ChromeDriver(); return driver; } return driver; }} |
Now lets take a look at how our Manager class would look like. The Manager class essentially uses a concept in java called ThreadLocal variables.
The code would look like below :
package execution.parallel;import org.openqa.selenium.WebDriver;public class LocalDriverManager { private static ThreadLocalnew ThreadLocal public static WebDriver getDriver() { return webDriver.get(); } static void setWebDriver(WebDriver driver) { webDriver.set(driver); }} |
package execution.parallel;import org.openqa.selenium.WebDriver;import org.testng.IInvokedMethod;import org.testng.IInvokedMethodListener;import org.testng.ITestResult;public class WebDriverListener implements IInvokedMethodListener { @Override public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { if (method.isTestMethod()) { String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName"); WebDriver driver = LocalDriverFactory.createInstance(browserName); LocalDriverManager.setWebDriver(driver); } } @Override public void afterInvocation(IInvokedMethod method, ITestResult testResult) { if (method.isTestMethod()) { WebDriver driver = LocalDriverManager.getDriver(); if (driver != null) { driver.quit(); } } }} |
package execution.parallel;import org.testng.annotations.Test;public class ThreadLocalDemo { @Test public void testMethod1() { } @Test public void testMethod2() { } private void invokeBrowser(String url) { System.out.println("Thread id = " + Thread.currentThread().getId()); System.out.println("Hashcode of webDriver instance = " + LocalDriverManager.getDriver().hashCode()); LocalDriverManager.getDriver().get(url); }} |
We are printing the hashCode() values for the browser to demonstrate the fact that there are unique and different webDriver instances being created for every test method. [ Remember hashCode() value for an object would always be unique ]
Now lets take a look at how our suite file looks like :
<suite name="Suite" parallel="methods"><listeners><listener class-name="organized.parallel.WebDriverListener"></listener></listeners> <test name="Test"> <parameter name="browserName" value="firefox"></parameter> <classes> <class name="organized.parallel.ThreadLocalDemo" /> </classes> </test> </suite> |
12
| [TestNG] Running: /githome/PlayGround/testbed/src/test/resources/threadLocalDem.xmlThread id = 10Hashcode of webDriver instance = 1921042184Thread id = 9Hashcode of webDriver instance = 2017986718===============================================SuiteTotal tests run: 2, Failures: 0, Skips: 0=============================================== |
Comments