0
<test name="abc">
  <classes>
    <class name="myClass">
       **<exclude name="testMethod" invocation-numbers="4"/>**
    </class>
  </classes>
</test>

The above testng XML simply excludes the "testMethod" as a whole. However, if I replace "exclude" with "include", it correctly runs only the 5th iteration of the data provider as the test data. When this is the case for include, when I put exclude, testng should run all the iterations of the "testMethod" excluding the 5th iteration of the data provider. But it simply excludes that method as a whole. Why is this so? What should be the workaround to achieve my expectation?

Ela
  • 313
  • 3
  • 14

1 Answers1

1

AFAIK, You cannot do this via the testng.xml file.

It is easy to specify the iterations to be executed without having to know the data set size, but it would be impossible to do that when you are excluding a particular iteration.

The easiest way that I can think of is by plugging in this filtering logic within your data provider. Here's a sample that shows you how to do this :

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class SampleTestClass {

    @Test(dataProvider = "dp")
    public void testMethod(int value) {
        System.out.println("Value is " + value);
    }

    @DataProvider(name = "dp")
    public Object[][] getData() {
        Object[][] data = new Object[][]{
                {1},
                {2},
                {3},
                {4},
                {5}
        };

        //Calculate how many parameters we will be providing the @Test method for every iteration.
        int numberOfParameters = data[0].length;

        //Get the list of iterations to exclude from the user as comma separated values
        //Here for the sake of example we are simulating that only the 3rd iteration needs to be excluded.
        String exclude = System.getProperty("exclude", "3");
        if (exclude == null || exclude.trim().isEmpty()) {
            return data;
        }
        //Translate that comma separated values into a list of integers
        List<Integer> excludeValues = Arrays.stream(exclude.split(","))
                .map(Integer::parseInt).collect(Collectors.toList());
        Object[][] finalData = data;
        //Now nullify all the rows which we were asked to exclude so that its easy for us to filter out all the non
        //null values.
        excludeValues.forEach(value -> finalData[value] = null);
        Object[] newData = Arrays.stream(data).filter(Objects::nonNull).collect(Collectors.toList()).toArray();

        //Lets copy the contents back to the original array
        data = new Object[newData.length][numberOfParameters];
        for (int i=0;i<newData.length;i++) {
            data[i] = (Object[]) newData[i];
        }
        return data;
    }
}
Krishnan Mahadevan
  • 14,121
  • 6
  • 34
  • 66