TestNG flexible dataProvider

I thought to share with you guys a flexible way of defining TestNG DataProvider. As you already might know, dataprovider is a powerful Java annotation that can be used as parameters injection.

Let’s assume you get a set of test data supplied by the business as CSV format. Let’s keep it simple and imagine it has three columns below:

Firstname Lastname Age
Johnson Pietser 29
Eve Bue 56
Peter Halulja 43

The first thing is to convert the CSV into a class, such as Customer class.

public class Customer {
    private String firstName;
    private String lastName;
    private int age;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

After that create a test class, in our case we called it DemoTest.class

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by TripleQA
 */
public class DemoTest {

    @DataProvider(name = "customersData")
    public Object[][] createCustomersData() throws IOException {

        Object[][] arr = new Object[getCustomerData().size()][1];

        for(int i =0; i < getCustomerData().size();i++){
            arr[i][0] = getCustomerData().get(i);
        }

        return arr;
    }

    @Test(dataProvider = "customersData")
    public void testCustomerData(Customer customer) {
        // do your testing with the every test customer....
       System.out.println(customer.getFirstName() + " - " + customer.getLastName() + " - " + customer.getAge());

    }

    private List<Customer> getCustomerData() throws IOException {
        String fileName = "customer.csv";
        List<Customer> customersData = new ArrayList<Customer>();

        BufferedReader bReader = new BufferedReader(new InputStreamReader(
                this.getClass().getResourceAsStream("/" + fileName)));

        Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(bReader);
        for (CSVRecord record : records) {
            Customer customer = new Customer();
            customer.setFirstName(record.get(0));
            customer.setLastName(record.get(1));
            customer.setAge(Integer.valueOf(record.get(2)));
            customersData.add(customer);
        }
        return customersData;
    }

}

The code is hopefully self explained, but let’s have deeper look at the dataProvider method:

@DataProvider(name = "customersData")
public Object[][] createCustomersData() throws IOException {

  Object[][] arr = new Object[getCustomerData().size()][1];

  for(int i =0; i < getCustomerData().size();i++){
    arr[i][0] = getCustomerData().get(i);
  }
  return arr;
}

This piece of code is invoking the getCustomerData private method, which returns a list of Customer objects. Further it loops through the list and adds into the two dimensional array.

The test method below will make use of the dataprovider by refering it to its name. This will call the method for every customer.

  @Test(dataProvider = "customersData")
  public void testCustomerData(Customer customer) {
        // do your testing with the every test customer....
  }

The flexibility is that you only have to update the CSV data source file and no other coding is required. The data driven testing comes here into picture :).

2 thoughts on “TestNG flexible dataProvider

  1. Found an issue in code: createCustomersData contains 3 unnecessary calls to getCustomerData(), in terms of performance it is not good.
    Just calls it once and reuse urlData later in code:

    @DataProvider(name = “customersData”)
    public Object[][] createCustomersData() throws IOException {
    List urlData = csvReader.getCustomerData();
    Object[][] arr = new Object[urlData.size()][1];

    for(int i =0; i <urlData.size();i++){
    arr[i][0] = urlData.get(i);
    }

    return arr;
    }

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s