Parameterized
tests are used to repeat the same test against different input values.
For
example, I written an application that compute the factorial of a number.
package com.sample.arithmetic; public class Factorial { public int factorial(int num) throws Exception { if (num < 0) { throw new IllegalArgumentException("Factorial is not computed for negative numbers"); } int result = 1; for (int i = 2; i <= num; i++) { result *= i; } return result; } }
I
would like to test the above application with below input-output combinations.
Input
|
Expected Output
|
0
|
1
|
1
|
1
|
5
|
120
|
10
|
3628800
|
I
written the test application like below.
FactorialTest.java
package com.sample.arithmetic; import static org.junit.Assert.assertEquals; import org.junit.Test; /** * Test cases follow below naming convention. methodName_input_output format. * * @author krishna * */ public class FactorialTest { @Test public void factorial_0_1() throws Exception { Factorial factorial = new Factorial(); long actual = factorial.factorial(0); long expected = 1; assertEquals(expected, actual); } @Test public void factorial_1_1() throws Exception { Factorial factorial = new Factorial(); long actual = factorial.factorial(1); long expected = 1; assertEquals(expected, actual); } @Test public void factorial_5_120() throws Exception { Factorial factorial = new Factorial(); int actual = factorial.factorial(5); int expected = 120; assertEquals(expected, actual); } @Test public void factorial_10_3628800() throws Exception { Factorial factorial = new Factorial(); int actual = factorial.factorial(10); int expected = 3628800; assertEquals(expected, actual); } }
As
you observe above test class, all the test cases following the same pattern and
leads to lot of redundant code.
a.
Calling
the factorial function with some input
b.
Verifying
the output with expected value.
By
using parameterized test, you can remove this redundant code.
Step 1: Create a parameterized test class.
@RunWith(Parameterized.class)
public
class FactorialTest {
}
Step 2: Define input and
expectedResult fields.
Step 3: Define a constructor
that initializes input and expectedResult fields.
Step 4: Create a static
method that generates and returns test data. Annotate the static method with
‘@parameterized.Parameters’ annotation.
Step 5: Now write the test
case.
@Test
public void testFactorial() throws
Exception {
int output = fact.factorial(input);
assertEquals(expectedResult,
output);
}
Find
the below working example.
FactorialTest.java
package com.sample.arithmetic; import static org.junit.Assert.assertEquals; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; /** * Test cases follow below naming convention. methodName_input_output format. * * @author krishna * */ @RunWith(Parameterized.class) public class FactorialTest { private int input; private int expectedResult; private Factorial fact; @Before public void init() { fact = new Factorial(); } @Parameterized.Parameters public static Iterable<Object[]> data() { return Arrays.asList(new Object[][] { { 0, 1 }, { 1, 1 }, { 5, 120 }, { 10, 3628800 } }); } public FactorialTest(int input, int expectedResult) { this.input = input; this.expectedResult = expectedResult; } @Test public void testFactorial() throws Exception { int output = fact.factorial(input); assertEquals(expectedResult, output); } }
No comments:
Post a Comment