Just wanted to post an update on using TestNG’s @Factory with @DataProvider.
A few gotcha’s you may encounter:
1) When placing your @DataProvider and @Factory inside the test class you cannot place @Test on the class itself. In the following example doing so will result in: org.testng.TestNGException:
Method createExampleClass requires 3 parameters but 0 were supplied in the @Test annotation.
2) Make sure to create your @Factory and @DataProvider methods as static
ExampleClass:
public class ExampleClass { @DataProvider(name = "data") public static Iterator<Object[]> getData() { List<Object[]> data = new ArrayList<Object[]>(); //Our array types must match the @Factory input (String, Integer, Boolean) data.add(new Object[]{"Object 1", 1, true}); data.add(new Object[]{"Object 2", 2, false}); return data.iterator(); } @Factory(dataProvider = "data") public static Object[] createExampleClass(String s, Integer i, Boolean b) { //Instantiate the @Test class supplying the constructor our values return new Object[]{new ExampleClass(s, i, b)}; } private String s; private Integer i; private Boolean b; //Created with values from @DataProvider in @Factory public ExampleClass(String s, Integer i, Boolean b) { this.s = s; this.i = i; this.b = b; } @Test public void unitTest() { System.out.println(s + ", " + i + ", " + b); } }
Another “preferred” way to use the constructor as the factory:
public class ExampleClass { @DataProvider(name = "data") public static Iterator<Object[]> getData() { List<Object[]> data = new ArrayList<Object[]>(); //Our array types must match the @Factory input (String, Integer, Boolean) data.add(new Object[]{"Object 1", 1, true}); data.add(new Object[]{"Object 2", 2, false}); return data.iterator(); } private String s; private Integer i; private Boolean b; //Created with values from @DataProvider @Factory(dataProvider = "data") public ExampleClass(String s, Integer i, Boolean b) { this.s = s; this.i = i; this.b = b; } @Test public void unitTest() { System.out.println(s + ", " + i + ", " + b); } }