6
votes

I have this code for testing a site with selenium webdriver. There are four @Test methods, and a @DataProvider with three values. So, in total twelve tests get run.

public class SomeTest {

    WebDriver driver;

    @DataProvider(name = "URLs")
    public Object[][] createData1() {
     return new Object[][] {
       {"url 1"},
       {"url 2"},
       {"url 3"}};
    }

    @BeforeMethod
    //right now I'm just setting up weddriver for chrome, but 
    //I'll need to run this test for firefox, chrome, and IE
    public void setUpWebDriver(){
        driver = WebDrivers.getChromeDriver();
    }

    @AfterMethod
    public void closeWebDriver(){
        driver.quit();
    }   

    //test methods below

    @Test(dataProvider = "URLs")
    public void test1(String url){
        //test 1 with url
    }

    @Test(dataProvider = "URLs")
    public void test2(String url){
        //test 2 with url
    }

    @Test(dataProvider = "URLs")
    public void test3(String url){
        //test 3 with url
    }

    @Test(dataProvider = "URLs")
    public void test4(String url){
        //test 4 with url
    }

}

Right now, these tests are running under Chrome. But I also want to repeat all of these tests, with all of the data provider variations, on Firefox and Internet explorer. How can I get the entire class of tests to repeat for these other webdrivers? It's almost like I need a @DataProvider for the entire class (for the beforemethod).

2
I had the same problem when I was using Selenium + TestNG for my web application testing project. I asked for help on the TestNG mailing list and received some, but I never found a solution I really liked.reinierpost

2 Answers

9
votes

You should use a @Factory.

public class SomeTest {

    @Factory
    public Object[] createInstances() {
        Object[] result = new Object[]{            
            new SomeTest(WebDrivers.getChromeDriver())
            // you can add other drivers here
        };
        return result;
    }

    private final WebDriver driver;

    public SomeTest(WebDriver driver) {
        this.driver = driver
    }

    @DataProvider(name = "URLs")
    public Object[][] createData1() {
     return new Object[][] {
       {"url 1"},
       {"url 2"},
       {"url 3"}};
    }    

    @AfterClass
    public void closeWebDriver(){
        driver.quit();
    }   

    //test methods below

    @Test(dataProvider = "URLs")
    public void test1(String url){
        //test 1 with url
    }

    @Test(dataProvider = "URLs")
    public void test2(String url){
        //test 2 with url
    }

    @Test(dataProvider = "URLs")
    public void test3(String url){
        //test 3 with url
    }

    @Test(dataProvider = "URLs")
    public void test4(String url){
        //test 4 with url
    }

}
4
votes

I hope you are running the test cases from the TestNG.xml file. If yes, you can make use of the parameters provided by TestNG and configure the TestNG.xml file to run the test cases as follows.

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite1" verbose="1" >
    <test name="Internet Explorer Test" >
        <parameter name="browser" value="IE">
        <classes>
            <class name="com.somePackage.SomeTest" />
        </classes>
    </test>

    <test name="Firefox Test" >
        <parameter name="browser" value="FF">
        <classes>
            <class name="com.somePackage.SomeTest" />
        </classes>
    </test>

    <test name="Chrome Test" >
        <parameter name="browser" value="CH">
        <classes>
            <class name="com.somePackage.SomeTest" />
        </classes>
    </test>
</suite>

Some change is required for the @BeforeMethod as well.

@BeforeMethod
@Parameters{"browser"}
public void setUpWebDriver(String  browser){
    if (browser.equals("IE"))
        driver = WebDrivers.getIEDriver();
    else if (browser.equals("FF"))
        driver = WebDrivers.getFireFoxDriver();
    else if (browser.equals("CH"))
        driver = WebDrivers.getChromeDriver();
}