Search code examples
javatestngxlstestng-dataprovider

Issues with Dataprovider with validation functions for each row in xls


I have the following class

pulbic class DataProiders {

@DataProvider(name="data")
public String[][] getAllData() throws IOException {
// Using XLUtils class which uses XSSWorkbook to get cell data
//Take the  name of the xls file and sheet name and calculate row and column count
//two for loops rowcount and columncount to get all data and return the data
}

//I have the test clsss test.java
public class CutomerRecords {

pulbic Response response;
public static JSONObject resJsonObj;

@Test(priority = 1, dataProvider = "data", dataProviderClass = DataProviders.class)
public void CustomerData(String cId, String fName, String lName, String email, String postCode){
//These are the 5 columns in the xls sheet
//set method to set all the parameters using pojo class for request

//Call the POST API and get the response back
response = PostMehtodFromAPIClass(request)
resJsonOj= new JSONObject(response.getBody().asString());
}

@Test(priority=2)
public void validateResponseCusID(){
//my validation logic using resJsonObj
}

@Test(priority=2)
public void validateResponseCusName(){
//my validation logic using resJsonObj
}

@Test(priority=2)
public void validateResponseCusPostCode(){
//my validation logic using resJsonObj
}

@Test(priority=2)
public void validateResponseCusEmail(){
//my validation logic using resJsonObj
}

Here, my requirement is first execute CustomerData for first row in xls sheet and continue the each validation responbse test functions, then read the second row and test validate resonse.

But what is happening is if I have 5 rows in xls, it executes 5 rows and only for last row the validation response functions are working. I need a suggestion to read one row at atime and call the validation functions, then second row and validations, and so on.


Solution

  • The problem is in your test code. You are having a static data member which is going to remember the last assignment. That explains why the other two tests are basically only executing for the last iteration.

    What you need is a TestNG factory.

    Here's a sample that shows how to work with factories.

    public record Student(int id, String name, String address) { }
    
    import org.testng.annotations.DataProvider;
    
    public class DataProviders {
    
        @DataProvider(name = "data")
        public Object[][] getAllData() {
            return new Object[][]{
                    {new Student(20, "Alpha", "Chennai")},
                    {new Student(22, "Beta", "Bangalore")},
                    {new Student(23, "Gamma", "Hyderabad")},
            };
        }
    }
    
    import com.google.gson.Gson;
    import com.google.gson.JsonObject;
    import org.testng.annotations.Factory;
    import org.testng.annotations.Test;
    
    public class CustomerRecordsTest {
    
        private final Student student;
        private JsonObject resJsonObj;
        private static final Gson gson = new Gson();
    
        @Factory(dataProvider = "data", dataProviderClass = DataProviders.class)
        public CustomerRecordsTest(Student student) {
            this.student = student;
        }
    
        @Test(priority = 1)
        public void customerData() {
            resJsonObj = gson.fromJson(gson.toJson(student), JsonObject.class);
        }
    
        @Test(priority=2)
        public void validateResponseCusID(){
            System.err.println("Student id = " + resJsonObj.get("id"));
        }
    
        @Test(priority=3)
        public void validateResponseCusName(){
            System.err.println("Student name = " + resJsonObj.get("name"));
        }
    
        @Test(priority=4)
        public void validateResponseCusPostCode(){
            System.err.println("Student address = " + resJsonObj.get("address"));
        }
    }
    

    For more details on TestNG factories refer to : https://testng.org/#_factories