This rule raises an issue when a method annotated with TestNG’s @DataProvider returns a type that is not runtime-compatible with
TestNG’s expected return types.
TestNG relies on the @DataProvider annotation to supply test data for parameterized tests. At runtime, TestNG expects
@DataProvider methods to return one of these types:
Object[][] or any covariant reference array such as String[][] - a two-dimensional array where each inner array
represents parameters for one test invocationIterator<Object[]> (or Iterator<String[]>, etc.) - an iterator of arrays for lazy evaluation of test
dataObject[] or any covariant reference array such as String[] - an array where each element is itself an
Object[] (available since TestNG 6.x)Because Java reference arrays are covariant, a String[][] is assignable to Object[][] at runtime, and TestNG can process
it just like Object[][]. The same applies to String[] being assignable to Object[]. However, primitive arrays
such as int[] or int[][] are not reference types and cannot be assigned to Object[] or
Object[][], so TestNG cannot use them.
When a @DataProvider method returns an incompatible type (such as List, Stream, or a primitive array),
TestNG cannot process the data correctly. This causes test failures at runtime, even though the code may compile successfully.
Using the wrong return type breaks the runtime contract between your test code and the TestNG framework, leading to:
When a @DataProvider method returns an invalid type, the immediate impact is test execution failure. TestNG will throw a runtime
exception when attempting to invoke the test method with the provided data.
This has several consequences:
In CI/CD pipelines, this can block deployments and require emergency fixes to restore test coverage.
Use Object[][] when you have a fixed set of test data. Each inner array represents the parameters for one test invocation.
@DataProvider
public List<String> provideData() { // Noncompliant
return Arrays.asList("value1", "value2", "value3");
}
@DataProvider
public Object[][] provideData() {
return new Object[][] {
{"value1"},
{"value2"},
{"value3"}
};
}
Use Iterator<Object[]> when you need lazy evaluation or want to generate test data on-the-fly. This is useful for large datasets
or when data generation is expensive. Iterator<String[]> is also valid since String[] is assignable to
Object[].
@DataProvider
public Stream<String> provideData() { // Noncompliant
return Stream.of("value1", "value2", "value3");
}
@DataProvider
public Iterator<Object[]> provideData() {
return Arrays.asList(
new Object[]{"value1"},
new Object[]{"value2"},
new Object[]{"value3"}
).iterator();
}
Covariant reference arrays such as String[] are assignable to Object[] and are accepted by TestNG. However, primitive
arrays such as int[] are not reference arrays and are rejected at runtime.
@DataProvider
public int[] provideIds() { // Noncompliant, primitive arrays are not assignable to Object[]
return new int[]{1, 2, 3};
}
@DataProvider
public String[] provideData() { // Compliant, String[] is assignable to Object[]
return new String[]{"value1", "value2", "value3"};
}