Providing TestNG factory with data provider to invoke test methods - Not able to invoke test multiple times

Viewed 224

I have used test dat provider and factory with sample data more like reading from excel rows with multiple values. So each Map denotes Column name and value of each row and adding it to list have all the values which are read from excel. Now am returning Object[][] of List<HashMap>, so in factory it has to be in same signature. Here if I put each list to map, then only only instance I can execute. Is there a way to have HashMap returned for each list index so that Test method executes based on the size of arraylist.

public class TestNG {
ArrayList<HashMap<String, String>> natives;
@DataProvider(name = "create")
public static Object[][] createData() {
    System.out.println("In data provider");
    ArrayList<HashMap<String, String>> check = new ArrayList<HashMap<String, String>>();
    HashMap<String, String> hash_map = new HashMap<String, String>();
    hash_map.put("2", "Two");
    hash_map.put("3", "Three");
    check.add(hash_map);
    HashMap<String, String> hash_map1 = new HashMap<String, String>();
    hash_map1.put("21", "Two1");
    hash_map1.put("31", "Three1");
    check.add(hash_map1);
    return new Object[][] { { check } };
}

@Test
public void test() {
    System.out.println("ID is " + Thread.currentThread().getId());
    System.out.println(natives);
}

@Factory(dataProvider = "create", dataProviderClass = TestNG.class)
public Object[] checking1(ArrayList<HashMap<String, String>> map) {
    System.out.println("In Factory");
    natives = map;
    return new Object[] { natives };

}

}

I see when I use return new Object[]{new HashMap<String,String> values, new HashMap<String,String> value}, test method will be invoked twice. So is there a way to achieve this with above approach?

I have looked into all possible solutions which are available but couldn't find anything concrete to approach.

Here is the output I get.

[RemoteTestNG] detected TestNG version 6.14.3
In data provider
In Factory
ID is 1
[{2=Two, 3=Three}, {31=Three1, 21=Two1}]

So, test method is called only once , since we are passing List on a whole which is understandable . But want it to execute number of times equal to list length. Any better way to approach?

1 Answers

Actually it looks like the Factory method is not required in this case. Since the whole list is passed as a single test case, the test is only executed once. You need to convert the list into an Object[][] where each test case would be a Map:

Either you could pass it as:

return new Object[][]{ {hash_map}, {hash_map1}};

OR if there are lot of maps in the list or if the list is populated from a different source, then you could do the following stream operation (if you are using java 8 or above). (If you are using a version below java 8, then you could use a for loop to do the same)

At the end of the data provider:

return check.stream()
            .map(m -> new Object[] { m } )
            .toArray(Object[][]::new);

Instead of using a factory you could modify the test as:

@Test(dataProvider = "create")
public void test(HashMap<String, String> map) {
    System.out.println("ID is " + Thread.currentThread().getId());
    System.out.println(map);
}
Related