JUnit 5 - @ParameterizedTest
Last Updated :
04 Feb, 2025
Parameterized tests in JUnit 5 provide the ability to run the same test multiple times with different inputs, helping to improve code coverage and catch edge cases that might otherwise go unnoticed By automating test execution with multiple sets of input data, parameterized tests simplify validation of various inputs scenarios, resulting in more robust and reliable code This approach reduces redundancy in test code, increases maintainability, and ensures that logic is n 'ade well under different circumstances.
When to Use @ParameterizedTest vs Regular Tests
- @ParameterizedTest: Use when you want to test some logic with different inputs. For example, evaluating a method for handling data formats, and handling inputs that may have different length, format, or threshold values.
- Routine Testing: Used when the logic is tested with only one input data or when the test is specific to a single case and does not require multiple runs of inputs
Dependencies
For the maven project category, add the below dependencie
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
For Gradle project category,
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.0'
Performance Considerations
Although @ParameterizedTest greatly improves coverage, note the potential performance impact, especially when using a large number of parameters. Using multiple iterations of testing with different input data can increase test execution time, especially for time- or resource-intensive tests.
- To reduce the number of test cases if some inputs are redundant.
- Grouping similar inputs to avoid unnecessary duplication.
- Using more efficient data generators.
Best Practices for Designing Parameterized Tests
- Use meaningful input data: Make sure your metrics are meaningful and reflect real-world conditions. This makes your tests more practical and helps identify real issues.
- Limit the number of parameters: While testing with multiple inputs is supported, multiple inputs can confuse testing, slow down, and make problem identification difficult Aim for the right combination of inputs than the most slow.
- Cluster-linked tests: When using parameterized tests, it is important that similar cases are logically classified. For example, the testing of valid inputs should be separated from the testing of passive inputs.
- Named Test Description: Ideally, a parameterized test should include a descriptive name that describes what the test does and what each input set represents.
- Use Custom Argument Providers: For complex arguments, consider creating custom ArgumentsProvider classes to provide input values. This improves readability and reusability.
Example 1:
Java
package testsuite;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
class StringUtilsTest {
@ParameterizedTest(name = "{index} => input={0}, expected={1}")
@CsvSource({
"'hello', 5",
"'JUnit', 4",
"'parameterized', 13"
})
void testStringLength(String input, int expectedLength) {
assertEquals(expectedLength, input.length());
}
}
Output:
Folder Structure:
JUnit Output:
Example 2:
Java
package testsuite;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ParameterizedTestExample1 {
@ParameterizedTest(name = "Addition Test #{index} - {0} + {1} = {2}")
@CsvSource({"1, 1, 2", "2, 3, 5", "5, 5, 10"})
void testAddition(int a, int b, int expectedResult)
{
Calculator calculator = new Calculator();
int result = calculator.add(a, b);
assertEquals(expectedResult, result, () -> {
return a + " + " + b + " should equal " + expectedResult + ", but the result is " + result;
});
}
private static class Calculator {
int add(int a, int b) {
return a + b;
}
}
}
Output:
Folder Structure:
JUnit Output:
Features of @ParameterizedTest
- Parameter Sources: The JUnit 5 supports various sources for providing input for the @ParameterizedTest method. Commonly used sources are @ValueSource provides a single Parameterized value for primitive or String value, @EnumSource which is used for enum types, @MethodSource is used for invokes a method to provide the parameters for testing method.
- Custom Conversion: By using Custom Conversion, we can be able to define customize Conversion to convert parameters to the types expected by the test method.
- Display Names: We can be able to create customize Display Names of the Parameterized tests to make the output more meaningful. And it helps to tester to understand the methods in script.
- Argument Accessors: You can use argument accessors to customize how parameters are accessed and passed to the test method.
- Null and Empty String Values: We can use null or empty string values in the parameterized tests to cover additional Sequence of events. The @NullSource and @EmptySource annotations can be used for this purpose.
- Exception Testing: Every Application needed exception handling then only the application can handle the unexpected errors in the functionality we can use the @ParameterizedTest annotation in combination with @Test to perform parameterized exception testing.
Summary
Key features of @ParameterizedTest
include its ability to,
- Reduce test redundancy by reusing the same logic with different inputs.
- Improve code coverage by running the same test under multiple conditions.
- Increase test clarity and maintainability by reducing the number of test methods.
When using parameterized tests,
- Always choose relevant and meaningful input values.
- Be mindful of performance when running tests with numerous parameters.
- Organize tests for readability and clarity.
Similar Reads
JUnit 5 - How to Write Parameterized Tests By using parameterized tests, we can reuse the single test configuration between multiple test cases. It will allow us to reduce the code base and easily verify multiple test cases without the need to create a separate test method for each one. This article will describe how we can develop parameter
10 min read
JUnit 5 â @RepeatedTest JUnit 5 is a powerful and flexible testing framework in the Java ecosystem, widely used for unit testing Java applications. It introduces several modern features that simplify testing, making it a preferred choice for developers. One of its common features is the @RepeatedTest annotation, which is d
5 min read
JUnit â Ordered Tests JUnit is a popular framework in the Java ecosystem designed for creating and executing automated tests. Although the framework encourages writing independent tests that can run in any order, there are scenarios where tests need to be executed in a specific order. This article explores how to order t
7 min read
JUnit 5 @Nested Test Classes JUnit 5 introduced several powerful features to make testing in Java more flexible and expressive. One of these features is the @Nested test classes, which allows for better organization of test cases by logically grouping them inside an outer test class. This can be particularly useful when dealing
6 min read
JUnit 5 â Test LifeCycle In the Java testing framework, JUnit 5 is the latest testing framework that introduces a robust test lifecycle that is managed through four primary annotations that are @BeforeAll, @BeforeEach, @AfterEach, and @AfterAll. We need to annotate each method with @Test annotation from the org.junit.jupite
5 min read