How to Use @ParameterizedTest in JUnit for Data-Driven Testing
Use
@ParameterizedTest in JUnit to run the same test method multiple times with different inputs. Combine it with annotations like @ValueSource or @CsvSource to provide test data. This helps test various cases without writing separate test methods.Syntax
The @ParameterizedTest annotation marks a test method to run multiple times with different parameters. You provide the parameters using source annotations like @ValueSource, @CsvSource, or others. The test method must accept parameters matching the data types provided.
- @ParameterizedTest: Marks the method as parameterized.
- @ValueSource: Supplies a single array of literals (ints, strings, etc.).
- @CsvSource: Supplies multiple comma-separated values per test run.
- Method parameters receive the data for each run.
java
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; class ExampleTest { @ParameterizedTest @ValueSource(strings = {"apple", "banana", "cherry"}) void testWithStrings(String fruit) { System.out.println(fruit); } }
Example
This example shows a parameterized test that checks if a number is even. It uses @ValueSource to provide multiple integers. The test runs once per number and asserts the number is even.
java
import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; class NumberTest { @ParameterizedTest @ValueSource(ints = {2, 4, 6, 8, 10}) void testIsEven(int number) { assertTrue(number % 2 == 0, number + " should be even"); } }
Output
Test passed 5 times with inputs: 2, 4, 6, 8, 10
Common Pitfalls
- Forgetting to add a source annotation like
@ValueSourcecauses the test not to run. - Method parameters must match the data types provided by the source exactly.
- Using unsupported types in
@ValueSourceleads to errors; use@CsvSourceor custom providers instead. - Mixing
@Testand@ParameterizedTeston the same method is invalid.
java
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; class WrongTest { // Wrong: No source annotation @ParameterizedTest void testWithoutSource(String input) { // This will fail to run } // Correct: @ParameterizedTest @ValueSource(strings = {"a", "b"}) void testWithSource(String input) { // Runs correctly } }
Quick Reference
| Annotation | Purpose | Example Usage |
|---|---|---|
| @ParameterizedTest | Marks a test method to run with multiple inputs | @ParameterizedTest |
| @ValueSource | Provides a single array of literals | @ValueSource(strings = {"a", "b"}) |
| @CsvSource | Provides multiple comma-separated values per run | @CsvSource({"1, 'one'", "2, 'two'"}) |
| @MethodSource | Uses a method to supply arguments | @MethodSource("methodName") |
Key Takeaways
Use @ParameterizedTest to run tests multiple times with different inputs.
Provide test data with source annotations like @ValueSource or @CsvSource.
Ensure method parameters match the types of provided data exactly.
Never forget to add a source annotation or the test won't run.
Use parameterized tests to reduce code duplication and improve coverage.