In this JUnit tutorial, learn to create and execute junit parameterized tests. A parameterized test is normal test, which is executed over and over with again using different test parameters. It helps developer to save time in executing same test with different input types to test function robustness and possibly function boundaries.
1. JUnit Maven Dependency
Below are maven dependencies, we should add in your maven project before testing example code.
<!-- Junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit-dep</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
2. JUnit parameterized test with constructor arguments
Parameterized test make use of @RunWith annotation along with @Parameters annotations to feed inputs.
2.1. Class to be tested
Below is the test class, we will write test case for.
package corejava.test.junit; public final class MathUtils { //Return square of a function public static int square(final int number) { return number * number; } }
2.2. Parameterized Tests
Lets write the parameterized tests for above math utility class.
package corejava.test.junit; import java.util.Arrays; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class JunitTestsWithParameters { // @Parameters annotation marks this method as parameters provider @Parameters(name = "Run #Square of : {0}^2={1}") public static Iterable<Object []> data() { return Arrays.asList(new Object[][] { { 1, 1 }, { 2, 4 }, { 3, 19 }, { 4, 16 }, { 5, 25 } }); } // Our two parameters private final int input; private final int resultExpected; // Constructor is initialized with one set of parameters every time public JunitTestsWithParameters(final int input, final int result) { this.input = input; this.resultExpected = result; } @Test public void testUserMapping() { // You can use here assert also Assert.assertEquals(resultExpected, MathUtils.square(input)); } }
Please note that –
- We must follow only given way to declare the parameter.
- Parameters are passes to class’s constructor to set in variables and thus be available in test cases.
- The return type of parameter class is “List []”, data types to be used have been limited to String or primitive value
Now check the program output.

3. JUnit parameterized test with field injection
To pass parameters to test, we can pass argument via field injection – rather than constructor arguments as well. In this approach, we declare exact number of fields as input parameters. One parameter per field.
Let’s retest our MathUtils
class with field injection. Notice how we replaced constructor with fields annotated with @Parameter annotation.
import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class JunitTestsWithFieldInjection { @Parameters(name = "Run #Square of : {0}^2={1}") public static Iterable<Object[]> data() { return Arrays.asList(new Object[][] { { 1, 1 }, { 2, 4 }, { 3, 9 }, { 4, 16 }, { 5, 25 } }); } @Parameter(value = 0) public int input; @Parameter(value = 1) public int resultExpected; @Test public void testSquare() { Assert.assertEquals(resultExpected, MathUtils.square(input)); } }
3.1. Single field injection
If we have only one field to inject, then we do not need to put value
attribute in @Parameter
annotation. Default value is always “value=0”.
import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class JunitTestsWithParameters { @Parameters(name = "Argument number {0} is positive") public static Iterable<Object[]> data() { return Arrays.asList(new Object[][] { { 0 }, { 1 }, { 2 }, { 3 }, { 4 } }); } @Parameter public int input; @Test public void testPositiveNumber() { Assert.assertEquals(true, input >= 0); } }
In this post, we learned to create parameterized tests and run multiple iterations of test with different parameters set. It helps to test method with parameters.
Happy Learning !!
Ashvin Kanani
What about using JUnit Theory instead using Parameterized runner, @Parameters and @Parameter annotations ?
meena
Hi Lokesh, Thank you for your awesome tutorials!! I want to write Junit for my REST service. Could you please write an article on how to write unit test for REST services. Thanks in advance!!
Lokesh Gupta
I will soon.
rajesh
How to write no of test cases in One Class using junit…
Rose
Hello
I am facing three issues when parameterising my class
Please help me !
1.When parametrising my first test(first value) always fails and give the error–org.openqa.selenium.WebDriverException: unknown error: keys should be a string
2.When accessing the excel sheet in some tests I am getting this error–java.lang.IllegalArgumentException: wrong number of arguments
Any clue?
Roserose
solved the first issue
second issue still seems to b there.Not able to access excel sheets created in excel 2010 .I am using pOI3.9
Fabio M.
Hi,
Nice article !!
I have problem with line 15 and the attribute name of the annotations Parameters.
The compilator says : “The attribute Name is undefined for the annotation type Parameterized.Parameters”.
Exists the attribute name in Parameters ?
Ciao
Fabio
Lokesh Gupta
Have you used Junit and dependencies version 4.11? As you see, i am using 4.11 here.