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 ThreadLocal new 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.xml Thread id = 10 Hashcode of webDriver instance = 1921042184 Thread id = 9 Hashcode of webDriver instance = 2017986718 =============================================== Suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== |
Comments