DEV Community

Cover image for How To Use DataProviders In TestNG
Kritika for LambdaTest

Posted on • Updated on • Originally published at lambdatest.com

How To Use DataProviders In TestNG

How To Use DataProviders In TestNG

In our earlier posts, we learned about using TestNG parameters in our TestNG scripts. To jog your memory, Parameterization In TestNG helps us pass data through the code and prevent hard-coding. However, TestNG parameters enable us to pass the values only once per execution cycle. To overcome this, we can use DataProvider in TestNG that allows us to pass multiple parameters to a single test in a single execution. Using DataProviders, we can easily pass multiple values to a test in just one execution cycle.

Let us quickly jump onto understanding more about DataProvider in TestNG and how we can efficiently use them in our test scripts for Selenium test automation.

What is a DataProvider in TestNG?

Similar to TestNG Parameters, DataProviders are a means to pass data to test scripts in TestNG. Using DataProvider in TestNG, we can easily inject multiple values into the same test case. It comes inbuilt in TestNG and is popularly used in data-driven frameworks.

The syntax for a DataProvider in TestNG is as follows:

@DataProvider(name = ”name of the data provider”)
public Object[][] dataProviderfunc(){
Return new Object[][]{
values
}
}
Enter fullscreen mode Exit fullscreen mode

Now, let’s try to understand the different components of this syntax.

  • The DataProvider annotation has a single attribute called name, which you can select as per your convenience.

  • DataProviders are separate methods used in test functions, which means that this annotation is not used on test functions like the testNG parameters.

  • The DataProvider method returns a 2D list of objects.

  • In case you do not define a name for the DataProvider, the DataProvider method name is considered its default name. So, the name of the DataProvider calls the DataProvider method.

With TestNG certification, you can challenge your skills in performing automated testing with TestNG and take your career to the next level.

Here’s a short glimpse of the TestNG certification from LambdaTest:

Try this online Grid to run your browser selenium automation testing scripts. Our cloud infrastructure has 3000+ desktop & mobile environments. Try for free!

Using DataProvider in TestNG

Now that you understand the basics of DataProviders, it is time to know how to use DataProvider in TestNG. DataProviders are most useful when you need to pass complex TestNG parameters. Shown below is a basic example of using the DataProvider in TestNG script.

package dataProviders;
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.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class SimpleTest {

    WebDriver driver;

    @DataProvider(name = "test-data")
    public Object[][] dataProvFunc(){
            return new Object[][]{
                {"Lambda Test"},{"Automation"}
            };
    }

    @BeforeMethod
      public void setUp() {

              System.out.println("Start test");
              System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
              driver = new ChromeDriver();
              String url = "https://www.google.com";
              driver.get(url);
              driver.manage().window().maximize();

      }
    //Passing the dataProvider to the test method through @Test annotation
    @Test(dataProvider ="test-data")
    public void search(String keyWord){
            WebElement txtBox = driver.findElement(By.xpath("//input[@class='gLFyf gsfi']"));
              txtBox.sendKeys(keyWord);
              Reporter.log("Keyword entered is : " +keyWord);
              txtBox.sendKeys(Keys.ENTER);
              Reporter.log("Search results are displayed.");
    }

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

}
Enter fullscreen mode Exit fullscreen mode

In the code above, I am passing two search keywords, viz “Lambda Test” and “Automation” to my test method using the DataProvider method. You can run the code and check the output. It will be as shown below-

Did you notice two values being passed to the search method while we ran the test just once?

That is the beauty of DataProvider! Let us try to clean up our code and inherit this DataProvider from another class. This is important because keeping everything in one place might become messy. Inheritance would come to our rescue then, let us see how in the next section.

If you want to know more about Event Listeners In Selenium WebDriver watch this video to learn how the Listeners “listen” to the event defined in the Selenium script and behave accordingly.

Automate Cypress testing and perform browser automation testing with LambdaTest. Our cloud infrastructure has 3000+ desktop & mobile environments. Try for free!

Inheriting DataProvider in TestNG

As mentioned above, DataProvider in TestNG plays an essential role in writing codes for complex projects or objects. While writing test cases, the code tends to get very messy. It is always preferred to declare the test case in one class and define TestNG parameters like DataProviders in another class. In other words, we are inheriting DataProvider from another file, and that is what inheriting a DataProvider in TestNG is all about. Let us create separate classes for the DataProvider method and the test method, as shown below:

DataProvider Class-

package dataProviders;
import org.testng.annotations.DataProvider; 
public class DPClass {
    @DataProvider(name = "test-data")
    public static Object[][] dataProvFunc(){
            return new Object[][]{
                {"Lambda Test"},{"Automation"}
            };
    }
}
Enter fullscreen mode Exit fullscreen mode

We can see that all we did was mark the DataProvider method as static and create a new class.

Test Class-

package dataProviders;
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.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestClass {
WebDriver driver;

    @BeforeMethod
      public void setUp() {
              System.out.println("Start test");
              System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
              driver = new ChromeDriver();
              String url = "https://www.google.com";
              driver.get(url);
              driver.manage().window().maximize();
          }

    @Test(dataProvider ="test-data", dataProviderClass=DPClass.class)
    public void search(String keyWord){
            WebElement txtBox = driver.findElement(By.xpath("//input[@class='gLFyf gsfi']"));
              txtBox.sendKeys(keyWord);
              Reporter.log("Keyword entered is : " +keyWord);
              txtBox.sendKeys(Keys.ENTER);
              Reporter.log("Search results are displayed.");
    }

    @AfterMethod
    public void burnDown(){
            driver.quit();
    }
}
Enter fullscreen mode Exit fullscreen mode

As you can see, to handle the inheritance, all we did was add an attribute to the test method (highlighted above), which specifies the class that has the DataProvider method. On running the above test, you will see the results similar to what we saw in our first execution.

Next, we will see passing multiple values for a single TestNG parameter using DataProvider in TestNG.

Passing Multiple Parameter Values in TestNG DataProviders

Passing multiple values is pretty similar to passing numerous parameters. The only difference is that we will pass various values to a single parameter so that a string of input(s) is sent in one go. Let us quickly understand it with the help of the code.

package dataProviders;
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.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class SimpleTest {
    WebDriver driver;
    @DataProvider(name = "test-data")
    public Object[][] dataProvFunc(){
            return new Object[][]{
                {"Selenium","Delhi"},{"QTP","Bangalore"},{"LoadRunner","Chennai"}
            };
    }
    @BeforeMethod
      public void setUp() {
              System.out.println("Start test");
              System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
              driver = new ChromeDriver();
              String url = "https://www.google.com";
              driver.get(url);
              driver.manage().window().maximize();

      }
    @Test(dataProvider ="test-data")
    public void search(String keyWord1, String keyWord2){
            WebElement txtBox = driver.findElement(By.xpath("//input[@class='gLFyf gsfi']"));
              txtBox.sendKeys(keyWord1," ",keyWord2);
              Reporter.log("Keyword entered is : " +keyWord1+ " " +keyWord2);
              txtBox.sendKeys(Keys.ENTER);
              Reporter.log("Search results are displayed.");
    }
    @AfterMethod
    public void burnDown(){
            driver.quit();
    }
}
Enter fullscreen mode Exit fullscreen mode

Run the test script, and you will see both the values for the TestNG parameters being passed in one go, the output for it would be as follows-

You might not know, but this is not the only way to read data in DataProviders. You can use external files to read the data and pass on to the test script through the DataProviders; one such external file is an Excel File. Next, we will see how to use an Excel file to fetch data and subsequently pass on to the DataProvider method. Without wasting any more time, let us walk through how this can be done.

DataProvider in TestNG using Excel

Using Excel for DataProvider in TestNG is one of the most convenient ways to read the data. By doing so, our job becomes extremely easy when dealing with vast amounts of data. To do so, we need to follow some simple steps in order to achieve our target of using Excel as a DataProvider.

Create a Test Data Sheet

Simply create a new package under your project directory and keep the external files under the same project. I have named my package as “testData” under which I am saving my data excel file “TestData.xlsx.” So, my datasheet looks like below-

Next, we will create a DataProvider method that will use another method to read the excel file & create a 2D object from the row & column values of the excel and return the same value, so that our test script can use it. The code for it would look like below-

@DataProvider(name ="excel-data")
    public Object[][] excelDP() throws IOException{
            //We are creating an object from the excel sheet data by calling a method that reads data from the excel stored locally in our system
            Object[][] arrObj = getExcelData("Location of the excel file in your local system","Name of the excel sheet where your data is placed");
            return arrObj;
    }
    //This method handles the excel - opens it and reads the data from the respective cells using a for-loop & returns it in the form of a string array
    public String[][] getExcelData(String fileName, String sheetName){

            String[][] data = null;     
        try
        {
        FileInputStream fis = new FileInputStream(fileName);
        XSSFWorkbook wb = new XSSFWorkbook(fis);
        XSSFSheet sh = wb.getSheet(sheetName);
        XSSFRow row = sh.getRow(0);
        int noOfRows = sh.getPhysicalNumberOfRows();
        int noOfCols = row.getLastCellNum();
        Cell cell;
        data = new String[noOfRows-1][noOfCols];
        for(int i =1; i<noOfRows;i++){
             for(int j=0;j<noOfCols;j++){
                   row = sh.getRow(i);
                   cell= row.getCell(j);
                   data[i-1][j] = cell.getStringCellValue();
               }
        }
        }
        catch (Exception e) {
               System.out.println("The exception is: " +e.getMessage());
                        }
            return data;
    }
Enter fullscreen mode Exit fullscreen mode

After doing so we can simply pass the Data Provider in TestNG to our test method and our final code would look like below:

package testNG;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
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.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ExcelDataProvider {

    WebDriver driver;
    @BeforeMethod
      public void setUp() {
              System.out.println("Start test");
              System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
              driver = new ChromeDriver();
              String url = "https://www.google.com";
              driver.get(url);
              driver.manage().window().maximize();

      }

    @DataProvider(name ="excel-data")
    public Object[][] excelDP() throws IOException{
            //We are creating an object from the excel sheet data by calling a method that reads data from the excel stored locally in our system
            Object[][] arrObj = getExcelData("Location of the excel file in your local system","Name
of the excel sheet where your data is placed");
            return arrObj;
    }
    //This method handles the excel - opens it and reads the data from the respective cells using a for-loop & returns it in the form of a string array
    public String[][] getExcelData(String fileName, String sheetName){

            String[][] data = null;     
        try
        {
        FileInputStream fis = new FileInputStream(fileName);
        XSSFWorkbook wb = new XSSFWorkbook(fis);
        XSSFSheet sh = wb.getSheet(sheetName);
        XSSFRow row = sh.getRow(0);
        int noOfRows = sh.getPhysicalNumberOfRows();
        int noOfCols = row.getLastCellNum();
        Cell cell;
        data = new String[noOfRows-1][noOfCols];

        for(int i =1; i<noOfRows;i++){
             for(int j=0;j<noOfCols;j++){
                   row = sh.getRow(i);
                   cell= row.getCell(j);
                   data[i-1][j] = cell.getStringCellValue();
               }
        }
        }
        catch (Exception e) {
               System.out.println("The exception is: " +e.getMessage());
            }
            return data;
    }
    @Test(dataProvider ="excel-data")
    public void search(String keyWord1, String keyWord2){
            WebElement txtBox = driver.findElement(By.xpath("//input[@class='gLFyf gsfi']"));
              txtBox.sendKeys(keyWord1," ",keyWord2);
              Reporter.log("Keyword entered is : " +keyWord1+ " " +keyWord2);
              txtBox.sendKeys(Keys.ENTER);
              Reporter.log("Search results are displayed.");
    }
    @AfterMethod
    public void burnDown(){
            driver.quit();
    }   
}
Enter fullscreen mode Exit fullscreen mode

Now on running this code you will see results like below-

Now, Automate Cypress cloud tests and perform browser automation testing with LambdaTest for free.

Conclusion

In this tutorial, we saw how easily TestNG parameters or utilities, like the DataProviders, enable us to execute our test scripts. When we might have n-number of data combinations to test, DataProvider in TestNG can be used without the hassle of hard-coding any test value in the scripts. This TestNG parameter is especially useful when you want to integrate your external data files like an Excel file into the same code. That is how DataProvider in TestNG plays a vital role in Selenium test automation scripts. I recommend you to run all the above codes and check the output. We must also note that a DataProvider in TestNG returns a 2-D array, unlike other TestNG parameters. We can leverage these TestNG parameters to make the best of existing Selenium test automation scripts or create new scripts. LambdaTest helps you run all your Selenium test automation for Testng scripts on an online Selenium grid for a combination of 2000+ browsers and operating systems.

Do you know how to create a TestNG XML file and execute Parallel testing?

Go ahead and try out some login functionality with different sets of data all passed into a single DataProvider method on your own and see how efficient the execution becomes.
Happy testing!

Top comments (0)