Reputation: 161
I am trying to run the test methods in parallel by using TestNg concept, but it's not working as expected. It's launching multiple browsers and creating each thread for each browser, but it's entering all the value in only one browser. Please help me out. Here browser object and extent reports object are thread safe. Please find the test methods.
This is the Test class that needs to be executed in parallel, but it's not working. It just launches multiple browsers and all the thread value feeding data to one browser itself.
package com.sonata.tests;
import java.util.Map;
import java.util.Properties;
import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import com.sonata.utility.DataReader;
import com.sonata.utility.DriverCreation;
import com.sonata.pages.ComplaintPage;
import com.sonata.pages.HomePage;
import com.sonata.pages.LoginPage;
public class ComplainTest extends DriverCreation {
private String browser;
private String url;
HomePage homeObject;
LoginPage loginObject;
ComplaintPage compObject;
DataReader dataReader = new DataReader();
@Parameters({ "url", "browser" })
@BeforeMethod
public void readProperties(String url, String browser) {
/*
* Properties prop = PropertiesReader.getProperty(); browser =
* prop.getProperty("browser.name"); url = prop.getProperty("app.url");
*/
this.browser = browser;
this.url = url;
}
@Test
public void createComplaintCaseWithDefault() {
setTestCaseName("TC-10672");
initExtent(testCaseName);
if (!dataReader.isTestCaseExecute(xlsReader, testCaseName)) {
logger.info("Test Case not executed as its run mode is NO");
throw new SkipException("");
}
Object[][] testData = dataReader.getTestData(xlsReader, testCaseName);
for (int t = 0; t < testData.length; t++) {
initDriver(browser);
homeObject = new HomePage(driver, report, wait, logger);
homeObject.goToHomepge(url);
@SuppressWarnings("unchecked")
Map<String, String> testDataMap = (Map<String, String>) testData[t][0];
loginObject = new LoginPage(driver, report, wait, logger);
loginObject.login(testDataMap.get("UserName"),
testDataMap.get("Password"));
compObject = new ComplaintPage(driver, report, wait, logger);
compObject.createCase(testDataMap.get("ComplaintType"),
testDataMap.get("CustomerName"),
testDataMap.get("ComplaintCategory"));
compObject.complaintPageVerification();
}
}
@Test
public void createComplaintCaseWithSensitive() {
setTestCaseName("TC-10692");
initExtent(testCaseName);
if (!dataReader.isTestCaseExecute(xlsReader, testCaseName)) {
logger.info("Test Case not executed as its run mode is NO");
throw new SkipException("");
}
Object[][] testData = dataReader.getTestData(xlsReader, testCaseName);
for (int t = 0; t < testData.length; t++) {
initDriver(browser);
homeObject = new HomePage(driver, report, wait, logger);
homeObject.goToHomepge(url);
@SuppressWarnings("unchecked")
Map<String, String> testDataMap = (Map<String, String>) testData[t][0];
loginObject = new LoginPage(driver, report, wait, logger);
loginObject.login(testDataMap.get("UserName"),
testDataMap.get("Password"));
compObject = new ComplaintPage(driver, report, wait, logger);
compObject.createCase(testDataMap.get("ComplaintType"),
testDataMap.get("CustomerName"),
testDataMap.get("ComplaintCategory"));
compObject.complaintPageVerification();
}
}
@Test
public void reopenComplaintFieldVerfication() {
setTestCaseName("TC-10958");
initExtent(testCaseName);
if (!dataReader.isTestCaseExecute(xlsReader, testCaseName)) {
logger.info("Test Case not executed as its run mode is NO");
throw new SkipException("");
}
Object[][] testData = dataReader.getTestData(xlsReader, testCaseName);
for (int t = 0; t < testData.length; t++) {
initDriver(browser);
homeObject = new HomePage(driver, report, wait, logger);
homeObject.goToHomepge(url);
@SuppressWarnings("unchecked")
Map<String, String> testDataMap = (Map<String, String>) testData[t][0];
loginObject = new LoginPage(driver, report, wait, logger);
loginObject.login(testDataMap.get("UserName"),
testDataMap.get("Password"));
compObject = new ComplaintPage(driver, report, wait, logger);
compObject.reopenReasonFieldVerification(testDataMap
.get("ComplaintID"));
}
}
@AfterMethod
public void closeBrowser() {
if (driver != null) {
homeObject.tearDownTest();
}
if (report != null) {
report.endTest();
}
}
}
This is the Driver class which will create the driver instance for each Test method.
package com.sonata.utility;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.LogStatus;
import com.sonata.constants.Constants;
public class DriverCreation {
public ExtentReports report;
public WebDriver driver;
public DesiredCapabilities cap1;
public WebDriverWait wait;
protected String testCaseName;
ExtentReport extent;
public Logger logger = Logger.getLogger(this.getClass().toString());
public ExcelReader xlsReader = new ExcelReader(getProjectPath()
+ Constants.XLS_FILE_PATH);
/*
* public DriverCreation(String browser,ExtentReports report,Logger logger){
* this.browser = browser; this.report = report; this.logger = logger; }
*/
public void initExtent(String reportName) {
extent = new ExtentReport();
report = extent.getExtentReportInstance(reportName);
}
public void setTestCaseName(String testCaseName){
this.testCaseName = testCaseName;
}
public WebDriver initDriver(String browser) {
try {
cap1 = new DesiredCapabilities();
if (!Constants.CONSTANTS_GRIDEXECUTION) {
if (browser.equalsIgnoreCase("Firefox")) {
System.setProperty("webdriver.gecko.driver",
Constants.CONSTANTS_GECKO_DRIVER_PATH);
cap1.setCapability("marionette", true);
/* ThreadLocal<WebDriver> driver1 = new ThreadLocal<WebDriver>(){
@Override
protected WebDriver initialValue(){
return new FirefoxDriver(cap1);
}
};*/
//driver = driver1.get();*/
driver= new FirefoxDriver(cap1);
driver.manage().timeouts()
.implicitlyWait(2, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 50);
report.log(LogStatus.INFO, "Firefox driver has started");
logger.info("Firefox driver has started");
} else if (browser.equalsIgnoreCase("Chrome")) {
System.setProperty(Constants.CONSTANTS_CHROME_PROPERTY,
Constants.CONSTANTS_CHROME_DRIVER_PATH);
/*driver1 = new ThreadLocal<WebDriver>(){
@Override
protected WebDriver initialValue(){
return new ChromeDriver();
}
};
driver = driver1.get();*/
driver = new ChromeDriver();
driver.manage().timeouts()
.implicitlyWait(2, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 50);
report.log(LogStatus.INFO, "Chrome driver has started");
logger.info("Chrome driver has started");
} else if (browser.equalsIgnoreCase("PhantomJS")) {
System.setProperty(Constants.CONSTANTS_PHANTOM_PROPERTY,
Constants.CONSTANTS_PHANTOM_DRIVER_PATH);
cap1.setJavascriptEnabled(true);
cap1.setCapability("takesScreenshot", true);
cap1.setCapability(
PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
Constants.CONSTANTS_PHANTOM_DRIVER_PATH);
/*ThreadLocal<WebDriver> driver1 = new ThreadLocal<WebDriver>(){
@Override
protected WebDriver initialValue(){
return new PhantomJSDriver(cap1);
}
};
driver = driver1.get();*/
driver = new PhantomJSDriver(cap1);
driver.manage().window().setSize(new Dimension(1920, 1200));
wait = new WebDriverWait(driver, 50);
report.log(LogStatus.INFO,
"PhantomJS/Ghost driver has started");
logger.info("PhantomJS/Ghost driver has started");
} else if (browser.equalsIgnoreCase("IE")) {
System.setProperty(Constants.CONSTANTS_IE_PROPERTY,
Constants.CONSTANTS_IE_DRIVER_PATH);
// cap1.internetExplorer();
cap1.setCapability(
InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION,
true);
/*ThreadLocal<WebDriver> driver1 = new ThreadLocal<WebDriver>(){
@Override
protected WebDriver initialValue(){
return new InternetExplorerDriver(cap1);
}
};
driver = driver1.get();*/
driver = new InternetExplorerDriver(cap1);
driver.manage().timeouts()
.implicitlyWait(2, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 50);
report.log(LogStatus.INFO,
"Internet Explorer driver has started");
logger.info("Internet Explorer driver has started");
}
} else {
String nodeUrl = Constants.CONSTANTS_IPDETAILS;
if (browser.equalsIgnoreCase("Firefox")) {
System.setProperty("webdriver.gecko.driver",
Constants.CONSTANTS_GECKO_DRIVER_PATH);
cap1.setCapability("marionette", true);
cap1 = DesiredCapabilities.firefox();
cap1.setBrowserName("firefox");
cap1.setPlatform(Platform.WINDOWS);
} else if (browser.equalsIgnoreCase("Chrome")) {
System.setProperty(Constants.CONSTANTS_CHROME_PROPERTY,
Constants.CONSTANTS_CHROME_DRIVER_PATH);
cap1 = DesiredCapabilities.chrome();
cap1.setBrowserName("chrome");
cap1.setPlatform(Platform.WINDOWS);
} else if (browser.equalsIgnoreCase("IE")) {
System.setProperty(Constants.CONSTANTS_IE_PROPERTY,
Constants.CONSTANTS_IE_DRIVER_PATH);
// cap1.internetExplorer();
cap1 = DesiredCapabilities.internetExplorer();
cap1.setBrowserName("internet explorer");
cap1.setPlatform(Platform.WINDOWS);
cap1.setCapability(
InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,
true);
cap1.setCapability(
InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION,
true);
}
ThreadLocal<WebDriver> driver1 = new ThreadLocal<WebDriver>(){
@Override
protected WebDriver initialValue(){
try {
return new RemoteWebDriver(new URL(nodeUrl), cap1);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
};
driver = driver1.get();
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 50);
report.log(LogStatus.INFO, browser + " driver has started");
logger.info(browser + " driver has started");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Assert.assertTrue(true, "Set up Test");
} catch (Exception e) {
logger.error("Try and catch block while assert " + e);
}
}
return driver;
}
private String getProjectPath() {
File currentDirFile = new File("");
String path = currentDirFile.getAbsolutePath();
return path;
}
}
TESTNG SUITE XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="C4C" thread-count="3" parallel="methods">
<parameter name="url" value="https://abc.xyz.ondemand.com/"/>
<parameter name="browser" value="Chrome"/>
<test name="Case" allow-return-values="true" group-by-instances="true">
<classes>
<class name="com.sonata.tests.ComplainTest" >
</class>
</classes>
</test>
</suite>
Upvotes: 3
Views: 665
Reputation: 8479
You are storing the driver at class level. But you parallelise based on methods. In this case one driver object will be there. I see the thread local lines were commented.
There are two ways to solve this issue,
One: As your running in method level and navigating the HomePage in each method, you can maintain driver object in method level,
Webdriver driver = initDriver(browser);
homeObject = new HomePage(driver, report, wait, logger);
homeObject.goToHomepge(url);
Other way: you can maintain the driver object in thread local in your driver creation class,
public class DriverCreation {
private static ThreadLocal<WebDriver> WEBDRIVER = new ThreadLocal<WebDriver>();
public WebDriver getWebDriver(String browser){
WebDriver driver= WEBDRIVER.get();
if (driver== null) {
driver = initDriver(browser);
WEBDRIVER.set(driver);
}
return driver;
}
}
And use it in test method in same way,
Webdriver driver = getWebDriver(browser);
homeObject = new HomePage(driver, report, wait, logger);
homeObject.goToHomepge(url);
The second one will create only one driver per thread while first one will create one driver per method. Handle the driver quit accordingly
Upvotes: 3