I want to run selenium tests in TestNg in parallel that use the @dataprovider. Ideally tests are parallel by method (one test = one method) and not simple suite parallelism by browser. I have read somewhere that about 5 instances of ChromeDriver can be controlled at a time so I thought this should be possible. Later I plan to move to grid2. For developement I'm running things with IntelliJ Idea test runner by right-click + run on the XML config file.
I had problems running my tests in parallel (on grid2 and locally) so I created a sample of more or less what I want to do.
Here is my test class
package tests;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.*;
import java.util.concurrent.TimeUnit;
import static org.testng.Assert.assertNotNull;
public class ParallelTest {
public static final String SEARCH_TERMS = "search-terms";
private WebDriver driver;
@BeforeMethod
@Parameters({"browser"})
public void beforeMethod(@Optional("chrome") String browser){
driver = getBrowser(browser);
driver.manage().deleteAllCookies();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
private WebDriver getBrowser(String browser) {
if(browser.equals("chrome")){
System.setProperty("webdriver.chrome.driver", "webdrivers\\chromedriver.exe");
return new ChromeDriver();
}
return new FirefoxDriver();
}
@AfterMethod
public void afterMethod(){
driver.quit();
}
@Test(description = "Check parallel selenium works.",
dataProvider = SEARCH_TERMS)
public void parallelSeleniumTest(String searchTerm){
driver.get("http://google.com");
WebElement search = driver.findElement(By.id("gbqfq"));
new Actions(driver)
.sendKeys(search, searchTerm)
.sendKeys(search, Keys.ENTER)
.perform();
String firstResult = driver.findElements(By.className("r")).get(0).getText();
assertNotNull(firstResult);
System.out.println(firstResult);
}
@DataProvider(name = SEARCH_TERMS, parallel = true)
public Object[][] getSearchTerms(){
return new Object[][]{
{"google"},
{"microsoft"},
{"facebook"},
{"amazon"},
{"apple"},
{"oracle"},
{"yahoo"},
{"jetbrains"},
{"intellij idea"},
{"selenium"},
{"java"},
{"testng"},
{"code"}
};
}
}
I threw in some native events since I use them heavily in my test suite.
And here is the TestNg xml config file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="4" name="vfr6-ui-tests" parallel="methods">
<test name="parallel-test-firefox">
<parameter name="browser" value="firefox"/>
<classes>
<class name="tests.ParallelTest"/>
</classes>
</test>
<test name="parallel-test-chrome">
<parameter name="browser" value="chrome"/>
<classes>
<class name="tests.ParallelTest"/>
</classes>
</test>
</suite>
I read instantiating one driver per test tends to be the most maintainable. The problem is that the firefox test runs in serial while the chrome test spits out all of the data points as test cases, attempts to open a trove of browser instances, then everything fails. My tests will have either 10-25 or 300-500 data points (cycling between either clients or clients x products).
What is the best way to set up the driver, dataprovider, and test runner to achieve the best parallelism in running tests?