6
votes

First of all, sorry for my english, it's not so perfect :)

So I'm facing with the following problem: I'm trying to run parallel tests in different browsers using Selenium Grid and TestNg and I pass the parameters in the @BeforeTest method. My problem is that when every test get initialized, it seems that they will use the last test's parameters. So in this example when I run the test, it will open two Chrome, instead of one Firefox and one Chrome. (The browser.getDriver() method returns a RemoteWebDriver)

TestNG.xml:

<suite thread-count="2" verbose="10" name="testSuite" parallel="tests">
  <test name="nameOfTheTestFirefox">
    <parameter name="platform" value="windows"/>
    <parameter name="browserVersion" value="32"/>
    <parameter name="browserName" value="firefox"/>
    <classes>
      <class name="example.test.login.LoginOverlayTest"/>
    </classes>
  </test> <!-- nameOfTheTestFirefox -->
  <test name="nameOfTheTestChrome">
    <parameter name="platform" value="windows"/>
    <parameter name="browserVersion" value="38"/>
    <parameter name="browserName" value="chrome"/>
    <classes>
      <class name="example.test.login.LoginOverlayTest"/>
    </classes>
  </test> <!-- nameOfTheTestChrome -->
</suite> <!-- testSuite -->

The AbstractTest class:

public class SeleniumTest {

    private static List<WebDriver> webDriverPool = Collections.synchronizedList(new ArrayList<WebDriver>());
    private static ThreadLocal<WebDriver> driverThread;
    public static BrowserSetup browser;

    @Parameters({ "browserName", "browserVersion", "platform"})
    @BeforeTest()
    public static void beforeTest(String browserName, @Optional("none") String browserVersion, String platform) throws WrongBrowserException, WrongPlatformException {

        final BrowserSetup browser = new BrowserSetup(browserName, browserVersion, platform);

        driverThread = new ThreadLocal<WebDriver>() {

            @Override
            protected WebDriver initialValue() {
                final WebDriver webDriver = browser.getDriver();
                webDriverPool.add(webDriver);
                return webDriver;
            }

        };

    }

    public static WebDriver getDriver() {
        return driverThread.get();
    }

    @AfterTest
    public static void afterTest() {
        for (WebDriver driver : webDriverPool) {
            driver.quit();
        }
    }

}

And my example @Tests:

@Test
public void test1() throws InterruptedException {
    WebDriver driver = getDriver();
    System.out.println("START: test1");
    driver.get("http://google.com");
    Thread.sleep(5000);
    System.out.println("END:  test1, title: " + driver.getTitle());
}

@Test
public void test2() throws InterruptedException {
    WebDriver driver = getDriver();
    System.out.println("START: test2");
    driver.get("http://amazon.com");
    Thread.sleep(5000);
    System.out.println("END:  test2, title: " + driver.getTitle());
}

@Test
public void test3() throws InterruptedException {
    WebDriver driver = getDriver();
    System.out.println("START: test3");
    driver.get("http://stackoverflow.com");
    Thread.sleep(5000);
    System.out.println("END:  test3, title: " + driver.getTitle());
}

So my question is how can I run the tests in parallel with the given parameters in separate threads?

Thanks in advance!

Peter

2

2 Answers

3
votes

Don't make the fields static.

private static List<WebDriver> webDriverPool = Collections.synchronizedList(new ArrayList<WebDriver>());
private static ThreadLocal<WebDriver> driverThread;
public static BrowserSetup browser;
2
votes

beforeTest() and afterTest() shouldn't be static if you want to run it in parallel, or make it synchronized to have it thread safe. Also, you do not use declared variable:

public static BrowserSetup browser; 

at all, or you missed something there since you also have:

final BrowserSetup browser = new BrowserSetup(browserName, browserVersion, platform);

inside beforeTest(...)