How To Use DataProviders In TestNG [With Examples]
DataProvider in TestNG is used to inject multiple values into the same test case, this guide explains how to use them in your Selenium test automation scripts.
Join the DZone community and get the full member experience.
Join For FreeParameterization 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:
xxxxxxxxxx
name = ”name of the data provider”) (
public Object[][] dataProviderfunc(){
Return new Object[][]{
values
}
}
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.
TestNG Annotations provide additional information about the class or method we defined above. It is usually represented by the ‘@’ prefix. TestNG uses these annotations to help in making a robust framework.
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.
xxxxxxxxxx
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;
(name = "test-data")
public Object[][] dataProvFunc(){
return new Object[][]{
{"Lambda Test"},{"Automation"}
};
}
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
(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.");
}
public void burnDown(){
driver.quit();
}
}
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! Another great thing about using TestNG are the interfaces known as listeners. TestNG listeners are modules that listen to certain events and keep track of test execution while performing some action at every stage of test execution.
Now, 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.
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
xxxxxxxxxx
package dataProviders;
import org.testng.annotations.DataProvider;
public class DPClass {
(name = "test-data")
public static Object[][] dataProvFunc(){
return new Object[][]{
{"Lambda Test"},{"Automation"}
};
}
}
We can see that all we did was mark the DataProvider method as static and create a new class.
Test Class-
xxxxxxxxxx
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;
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 ="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.");
}
public void burnDown(){
driver.quit();
}
}
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.
xxxxxxxxxx
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;
(name = "test-data")
public Object[][] dataProvFunc(){
return new Object[][]{
{"Selenium","Delhi"},{"QTP","Bangalore"},{"LoadRunner","Chennai"}
};
}
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 ="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.");
}
public void burnDown(){
driver.quit();
}
}
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 data sheet 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-
xxxxxxxxxx
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;
}
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();
}
}
Now on running this code you will see results like below:
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.
Happy testing!
Published at DZone with permission of Kritika Murari. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments