Parameterized
implements parameterized tests. When running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements. For example, to test a Fibonacci function, write:
@RunWith(Parameterized.class) public class FibonacciTest { @Parameters(name= "{index}: fib[{0}]={1}") public static Iterable<Object[]> data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } private int fInput; private int fExpected; public FibonacciTest(int input, int expected) { fInput= input; fExpected= expected; } @Test public void test() { assertEquals(fExpected, Fibonacci.compute(fInput)); } }
Each instance of FibonacciTest
will be constructed using the two-argument constructor and the data values in the @Parameters
method.
In order that you can easily identify the individual tests, you may provide a name for the @Parameters
annotation. This name is allowed to contain placeholders, which are replaced at runtime. The placeholders are
In the example given above, the Parameterized
runner creates names like [1: fib(3)=2]
. If you don't use the name parameter, then the current parameter index is used as name.
You can also write:
@RunWith(Parameterized.class) public class FibonacciTest { @Parameters public static Iterable<Object[]> data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } @Parameter(0) public int fInput; @Parameter(1) public int fExpected; @Test public void test() { assertEquals(fExpected, Fibonacci.compute(fInput)); } }
Each instance of FibonacciTest
will be constructed with the default constructor and fields annotated by @Parameter
will be initialized with the data values in the @Parameters
method.
The parameters can be provided as an array, too:
@Parameters public static Object[][] data() { return new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }; }
If your test needs a single parameter only, you don't have to wrap it with an array. Instead you can provide an Iterable
or an array of objects.
@Parameters public static Iterable<? extends Object> data() { return Arrays.asList("first test", "second test"); }
or
@Parameters public static Object[] data() { return new Object[] { "first test", "second test" }; }
By default the {@code Parameterized} runner creates a slightly modified{@link BlockJUnit4ClassRunner} for each set of parameters. You can build anown {@code Parameterized} runner that creates another runner for each set ofparameters. Therefore you have to build a {@link ParametersRunnerFactory}that creates a runner for each {@link TestWithParameters}. ( {@code TestWithParameters} are bundling the parameters and the test name.)The factory must have a public zero-arg constructor.
public class YourRunnerFactory implements ParameterizedRunnerFactory { public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError { return YourRunner(test); } }
Use the {@link UseParametersRunnerFactory} to tell the {@code Parameterized}runner that it should use your factory.
@RunWith(Parameterized.class) @UseParametersRunnerFactory(YourRunnerFactory.class) public class YourTest { ... }@since 4.0
|
|
|
|
|
|