One of the many excellent new features of JUnit 4 is parameterized tests. These are data-driven tests where a test case runs repeatedly against a collection of test data, as if each run were its own test case.
A standard example:
@RunWith(Parameterized.class)
public class ExampleDataDrivenTest {
public static final class Data {
private final String name;
public Data(final String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
private final List<Data> data;
public ExampleDataDrivenTest(final Data datum1, final Data datum2) {
System.out.println("ExampleDataDrivenTest");
this.data = asList(datum1, datum2);
}
@Test
public void dumpData() {
for (final Data datum : data)
System.out.println("datum = " + datum);
}
@Parameters
public static Collection<Data[]> data() {
final Data[][] data = new Data[][]{
{new Data("apple"), new Data("core")}};
return asList(data);
}
} This produces:
ExampleDataDrivenTest datum = apple datum = core
This works great for a fixed number of test data, but I want to test a variable number of data. The change is straight-forward once you recall that the varargs Java language feature is implemented as an array:
@RunWith(Parameterized.class)
public class ExampleDataDrivenTest {
public static final class Data {
private final String name;
public Data(final String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
private final List<Data> data;
public ExampleDataDrivenTest(final Data... data) {
System.out.println("ExampleDataDrivenTest");
this.data = asList(data);
}
@Test
public void dumpData() {
for (final Data datum : data)
System.out.println("datum = " + datum);
}
@Parameters
public static Collection<Data[][]> data() {
final Data[][][] data = new Data[][][]{
{{new Data("apple"), new Data("core")}}};
return asList(data);
}
} Reflect on the constructor and you see:
public ExampleDataDrivenTest(ExampleDataDrivenTest$Data[])
This makes the change more obvious.
I can now write my annotated parameters as:
@Parameters
public static Collection<Data[][]> data() {
final Data[][][] data = new Data[][][]{{{ /* no data */ }},
{{new Data("apple"), new Data("core")}},
{{new Data("baltimore")}}};
return asList(data);
} To produce:
ExampleDataDrivenTest ExampleDataDrivenTest datum = apple datum = core ExampleDataDrivenTest datum = baltimore