Parameterized tests are extremely useful when you need to test a series of inputs against the same functionality. JUnit offers Parameterized class that facilitates this purpose.
As usual, let's go through an example.
Assume you have a simple add method that takes 2 Integers and returns their sum. The Parameterized test for a such implementation would be:
@RunWith(Parameterized.class)
public class AdderTest extends TestCase {
@Parameterized.Parameters(name = "{index}: add[{0}, {1}]={2}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{0, 0, 0},
{1, 1, 2},
{2, 1, 3},
{100, 400, 500},
{99, 1, 100}
});
}
int input1;
int input2;
int expectedOutput;
public AdderTest(int i1, int i2, int expected) {
input1 = i1;
input2 = i2;
expectedOutput = expected;
}
@Test
public void testAdd() {
assertEquals(expectedOutput, Computer.add(input1, input2));
}
}
The test class constructor takes 3 arguments, the first input number, the second input number and the expected output respectively.
The data() method returns an array of 5 of objects, each containing 3 Integers.
During runtime, AdderTest will be instantiated 5 times, with the corresponding elements returned in the data() method.
The @Parameters annotation can be fed with a name, so that each test can be easily identified. The name contains placeholders for each parameter. Additionally, an "index" placeholder will keep track of the current parameter index.
When the test class is executed, the results will look like:
If the test method requires only a single argument, there is no need to wrap it in an array and can be implemented as shown below:
@Parameterized.Parameters
public static Object[] data() {
return new Object[]{"first test", "second test"};
}
or
@Parameterized.Parameters
public static Iterable<? extends Object> data() {
return Arrays.asList("first test", "second test");
}
Cheers!