I want to run selenium tests in parallel at TestNg, which use @dataprovider. Ideally, tests are parallel by method (one test = one method), rather than a simple set of parallelism by the browser. I read somewhere that about 5 instances of ChromeDriver can be controlled at the same time, so I thought it should be possible. Later I plan to go to grid2. For development, I run things with the IntelliJ Idea test runner by right-clicking + running the XML configuration 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 introduced some native events, as I used them heavily in my test suite.
And here is the TestNg xml configuration 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 that an instance of one driver per test is usually the most convenient to maintain. The problem is that the firefox test runs sequentially, while the chrome check spits out all the data points as test cases, tries to open a bunch of browser instances, then everything fails. My tests will have 10-25 or 300-500 data points (cyclic transition between customers or customers x products).
What is the best way to configure the driver, dataprovider, and test runner to achieve the best parallelism when running tests?