Enterprise Java

Parameterization with DataProvider in TestNG

Parameterization in TestNG is also known as Parametric Testing which allows testing an application against multiple test data and configurations. Though we have to consider the fact that exhaustive testing is impossible, however, it is necessary to check the behavior of our application against different sets of data that an end-user can pass. Time and manual effort saving have always been a primary reason for automating an application against all possible data combinations.

Hardcoding the test values every time in our test scripts is never said to be a good automation practice. To overcome this, the TestNG framework helps us with a parameterization feature in which we can parameterize different test values and even keep our test data separate from our test scripts.

Let’s consider an example that highlights the need for parameterization in test automation.

There are various websites that behave differently depending upon the different data entered by different end-users. Suppose, there’s a flight ticket booking web application which the end-users are using to check the flight availability for desired dates. We expect our application to show appropriate results according to the different places of origin and destination that the user enters. Hence, to test our application, we would pass different test data against the source and destination place to check if our application gives the correct results instead of the incorrect ones.

Parameterization in TestNG can be achieved in two ways:

  1. Using Parameter annotation with TestNG.xml file
  2. Using DataProvider annotation

In this article, we would be primarily focusing on the use of DataProvider in TestNG.

Significance of DataProvider in TestNG

Many times it so happens that we have to run our test methods against a huge set of test data to monitor application variant responses. In such cases, creating test scripts using @Parameter annotation with XML file might become a tedious process. To bypass this TestNG comes with @DataProvider annotation which helps us to achieve Data-Driven Testing of our application.

The DataProvider in TestNG prepares a list of test data and returns an array object of the same.

It is highly recommended to create a separate class file for TestNG DataProvider, this helps in maintaining the huge test data separately. If the test data values are small in number then you can also setup DataProvider in the same java file in which you have created your test cases.

Syntax of TestNG DataProvider

01
02
03
04
05
06
07
08
09
10
@DataProvider(name = “data - provider - name”, parallel = true)
public Object[][] supplyTestData() {
    return new Object[][] {
        {“
            First - test - value”
        }, {“
            Second - test - value”
        }
    }
}

Different components of the above syntax:

  1. The data provider method is set as a separate function from a test method, hence, it is marked with a @DataProvider annotation with below default parameters provided by TestNG:
    1. name: This highlights the name of a particular data provider. Further, this name is used with the @Test annotated method that wants to receive data from the @DataProvider. If the name parameter is not set in @DataProvider, then the name of this data provider will be automatically set as the name of the method.
    2. parallel: If this is set as true, the test method receiving value from the data provider will run in parallel. The default value is false.
  2. Since the TestNG DataProvider method returns a 2D list of objects, it is mandatory to create a data provider method of Object[][] type.

Note: To use DataProvider in TestNG, we need to import TestNG library: org.testng.annotations.DataProvider

Using DataProvider in TestNG framework

Now that we have understood the basic use of TestNG DataProvider, let’s have a look at some practical examples of flight ticket booking with the test data of multiple sources and destinations.

Java Test Class:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import io.github.bonigarcia.wdm.WebDriverManager;
 
 
public class SampleTestNgTest {
 
    private WebDriver driver;
 
    @BeforeMethod
    public void setup() {
 
        WebDriverManager.chromedriver().setup();
        ChromeOptions ops = new ChromeOptions();
        ops.addArguments(“–disable - notifications”);
        driver = new ChromeDriver(ops);
        driver.get(“https: //www.easemytrip.com/”);
            driver.manage().window().maximize();
        }
 
 
 
        @Test(dataProvider = “travel - source - destination”, dataProviderClass = TravelDataProvider.class)
        public void travel(String mySource, String myDestination) throws InterruptedException {
 
            WebElement source = driver.findElement(By.id(“FromSector_show”));
            source.clear();
            source.sendKeys(mySource);
 
            WebElement destination = driver.findElement(By.id(“Editbox13_show”));
            destination.clear();
            destination.sendKeys(myDestination);
 
            Thread.sleep(2000);
 
            WebElement searchButton = driver.findElement(By.cssSelector(“#search > input”));
            searchButton.click();
 
            String actualTitle = driver.getTitle();
            System.out.println(“Title
                for source: ”+mySource + ”and destination: ”+myDestination + ” = ”+actualTitle);
 
        }
 
        @AfterMethod
        public void tearDown() throws InterruptedException {
            Thread.sleep(2000);
            driver.quit();
        }
 
    }

Code Walkthrough:

In the above code, we have used TestNG DataProvider attributes as the parameters of Test annotation. Since we have created a separate class for DataProvider, it is necessary to provide the DataProvider name and class. The “travel” method parameters will automatically pick the values from the DataProvider list in the same order as they are defined. Please make sure that you are using the same DataProvider name in the Test annotation parameter else your test script would fail to execute.

If you are creating a DataProvider object list in the same java class in which you have created your test cases, then passing the DataProvider class name becomes optional in the Test annotation.

DataProvider Class:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
import org.testng.annotations.DataProvider;
 
public class TravelDataProvider {
 
    @DataProvider(name = “travel - source - destination”)
    public static Object[][] dataProviderMethod() {
        return new Object[][] {
            {“
                Delhi”,
                ”Singapore”
            }, {“
                Delhi”,
                ”Mumbai”
            }
        };
    }
 
}

Code Walkthrough:

Here we have created a simple DataProvider list for supplying multiple test data for our test automation. As mentioned above, DataProvider returns a 2-dimensional array object. We have used @DataProvider annotation here along with its “name” parameter, the same name has been used in our Test annotation parameter “dataProvider” in the previously linked code. Since we have created a data provider method in a separate class, it is mandatory to make the data provider method as static and use the “dataProviderClass” parameter to define the data provider class.

Console Output:

Types of Parameters Used in TestNG DataProviders

TestNG supports two types of parameters that can be used with data provider methods for greater flexibility of our automation scripts.

  1. Method: To fulfill a scenario where we can use the same data provider method to supply different test data to different test methods, the method parameter can be deemed beneficial. Let’s try this with an example:

Java Test Class:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import io.github.bonigarcia.wdm.WebDriverManager;
 
 
public class SampleTestNgTest {
 
    private WebDriver driver;
 
    @BeforeMethod
    public void setup() {
 
        WebDriverManager.chromedriver().setup();
        ChromeOptions ops = new ChromeOptions();
        ops.addArguments(“–disable - notifications”);
        driver = new ChromeDriver(ops);
        driver.get(“https: //www.easemytrip.com/”);
            driver.manage().window().maximize();
        }
 
 
 
        @Test(dataProvider = “travel - source - destination”, dataProviderClass = TravelDataProvider.class)
        public void domesticTravel(String mySource, String myDestination) throws InterruptedException {
 
            WebElement source = driver.findElement(By.id(“FromSector_show”));
            source.clear();
            source.sendKeys(mySource);
 
            WebElement destination = driver.findElement(By.id(“Editbox13_show”));
            destination.clear();
            destination.sendKeys(myDestination);
 
            Thread.sleep(2000);
 
            WebElement searchButton = driver.findElement(By.cssSelector(“#search > input”));
            searchButton.click();
 
            String actualTitle = driver.getTitle();
            System.out.println(“Title
                for source: ”+mySource + ”and destination: ”+myDestination + ” = ”+actualTitle);
 
        }
 
        @Test(dataProvider = “travel - source - destination”, dataProviderClass = TravelDataProvider.class)
        public void internationalTravel(String mySource, String myDestination) throws InterruptedException {
 
            WebElement source = driver.findElement(By.id(“FromSector_show”));
            source.clear();
            source.sendKeys(mySource);
 
            WebElement destination = driver.findElement(By.id(“Editbox13_show”));
            destination.clear();
            destination.sendKeys(myDestination);
 
            Thread.sleep(2000);
 
            WebElement searchButton = driver.findElement(By.cssSelector(“#search > input”));
            searchButton.click();
 
            String actualTitle = driver.getTitle();
            System.out.println(“Title
                for source: ”+mySource + ”and destination: ”+myDestination + ” = ”+actualTitle);
        }
 
        @AfterMethod
        public void tearDown() throws InterruptedException {
            Thread.sleep(2000);
            driver.quit();
        }
 
 
    }

DataProvider Class:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.lang.reflect.Method;
import org.testng.annotations.DataProvider;
 
public class TravelDataProvider {
 
    @DataProvider(name = “travel - source - destination”)
    public static Object[][] dataProviderMethod(Method m) {
        if (m.getName().equalsIgnoreCase(“domesticTravel”)) {
            return new Object[][] {
                {“
                    Delhi”,
                    ”Goa”
                }, {“
                    Delhi”,
                    ”Mumbai”
                }
            };
        } else {
            return new Object[][] {
                {“
                    Delhi”,
                    ”Sydney”
                }, {“
                    Delhi”,
                    ”Berlin”
                }
            };
        }
    }
 
}

Code Walkthrough and Output:

In this example, we have used the Method parameter to extract the name of the test method. Once extracted, we can return conditional test data for each test method.

Firstly, we have checked if our test method name is “domesticTravel”, if yes, then source and destination data are being supplied according to domestic places, else the data is being supplied according to international places.

  1. ITestContext: Many times we divide our test methods based on TestNG groups. In such a case, we might need different test data for different groups. TestNG DataProvider provides an advantage to cover such a scenario in just a single data provider method instead of creating a separate data provider method for supplying different test data to different groups. Let’s understand this with an example.

Java Test Class

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
 
import io.github.bonigarcia.wdm.WebDriverManager;
 
 
public class SampleTestNgTest {
 
    private WebDriver driver;
 
    @BeforeMethod(groups = {“
        domestic”,
        ”international”
    })
    public void setup() {
 
        WebDriverManager.chromedriver().setup();
        ChromeOptions ops = new ChromeOptions();
        ops.addArguments(“–disable - notifications”);
        driver = new ChromeDriver(ops);
        driver.get(“https: //www.easemytrip.com/”);
            driver.manage().window().maximize();
        }
 
 
 
        @Test(groups = “domestic”, dataProvider = “travel - source - destination”, dataProviderClass = TravelDataProvider.class)
        public void domesticTravel(String mySource, String myDestination) throws InterruptedException {
 
            WebElement source = driver.findElement(By.id(“FromSector_show”));
            source.clear();
            source.sendKeys(mySource);
 
            WebElement destination = driver.findElement(By.id(“Editbox13_show”));
            destination.clear();
            destination.sendKeys(myDestination);
 
            Thread.sleep(2000);
 
            WebElement searchButton = driver.findElement(By.cssSelector(“#search > input”));
            searchButton.click();
 
            String actualTitle = driver.getTitle();
            System.out.println(“Title
                for source: ”+mySource + ”and destination: ”+myDestination + ” = ”+actualTitle);
 
        }
 
        @Test(groups = “international”, dataProvider = “travel - source - destination”, dataProviderClass = TravelDataProvider.class)
        public void internationalTravel(String mySource, String myDestination) throws InterruptedException {
 
            WebElement source = driver.findElement(By.id(“FromSector_show”));
            source.clear();
            source.sendKeys(mySource);
 
            WebElement destination = driver.findElement(By.id(“Editbox13_show”));
            destination.clear();
            destination.sendKeys(myDestination);
 
            Thread.sleep(2000);
 
            WebElement searchButton = driver.findElement(By.cssSelector(“#search > input”));
            searchButton.click();
 
            String actualTitle = driver.getTitle();
            System.out.println(“Title
                for source: ”+mySource + ”and destination: ”+myDestination + ” = ”+actualTitle);
        }
 
        @AfterMethod(groups = {“
            domestic”,
            ”international”
        })
        public void tearDown() throws InterruptedException {
            Thread.sleep(2000);
            driver.quit();
        }
 
 
    }

DataProvider Class

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
 
public class TravelDataProvider {
 
    public static Object[][] travelData = null;
 
    @DataProvider(name = “travel - source - destination”)
    public static Object[][] dataProviderMethod(ITestContext c) {
        for (String group: c.getIncludedGroups()) {
 
            if (group.equalsIgnoreCase(“domestic”)) {
                travelData = new Object[][] {
                    {“
                        Delhi”,
                        ”Goa”
                    }, {“
                        Delhi”,
                        ”Mumbai”
                    }
                };
                break;
            } else if (group.equalsIgnoreCase(“international”)) {
                travelData = new Object[][] {
                    {“
                        Delhi”,
                        ”Sydney”
                    }, {“
                        Delhi”,
                        ”Berlin”
                    }
                };
                break;
            }
        }
        return travelData;
    }
 
}

TestNG.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<< ? xml version = ”1.0″ encoding = ”UTF - 8″ ? >
    <
    !DOCTYPE suite SYSTEM“ http : //beust.com/testng/testng-1.0.dtd” >
    <
    suite name = ”travel - test - suite” >
 
    <
    test name = ”Domestic Travel Test” >
 
    <
    groups >
    <
    run >
    <
    include name = ”domestic” / >
    <
    /run> <
    /groups>
 
    <
    classes >
    <
    class
name = ”main.java.src.SampleTestNgTest” / >
    <
    /classes>
 
    <
    /test>
 
 
    <
    test name = ”International Travel Test” >
 
    <
    groups >
    <
    run >
    <
    include name = ”international” / >
    <
    /run> <
    /groups>
 
    <
    classes >
    <
    class
name = ”main.java.src.SampleTestNgTest” / >
    <
    /classes>
 
    <
    /test>
 
    <
    /suite>

Code Walkthrough and Output:

In the above code- java test class, we have divided our test methods based on the group so that each group gets executed with different test data using a single data provider method.

In the TestNG data provider method, we have used the ITextContext interface to fetch the group name of each test method. Once fetched, the test method can be executed with multiple sets of data. One completely unique part that we have proposed with this method is to create a TestNG xml file. The purpose of creating an xml file is to command TestNG which test groups need to be executed and which test groups need to be ignored. In the testng.xml file, we have used a <groups> tag to include groups that need to be executed.

Note: Running group based tests directly from the java test class will throw an error. The java test class will first call a dataprovider in TestNG which currently doesn’t have any group information. Hence, it is important to execute group based tests from an xml file where we can define our group’s tag to provide test group information.

Conclusion

The use of parameterization in TestNG gives you the power to perform data-driven testing more efficiently. Defining the parameters beforehand will allow you to use different test inputs of a single test suite instead of writing multiple test automation scripts. Which in turn makes it easier to maintain the test automation code. Here is another helpful resource below that helps with understanding various rapid test automation techniques.

Published on Java Code Geeks with permission by Balamurugan, partner at our JCG program. See the original article here: Parameterization with DataProvider in TestNG

Opinions expressed by Java Code Geeks contributors are their own.

Balamurugan

Balamurugan works at pCloudy as a Brand Marketing. He has 8+ years of experience in SEO, SEM, Social media and Email Marketing. He likes to read current affairs, technology blogs and enjoys Carnatic music.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button