Parameterized tests allow you to run the same test multiple times with different inputs. This is particularly useful for testing functions that should behave the same way for a variety of inputs. In this section, we will cover how to create parameterized tests in JUnit.
Key Concepts
- Parameterized Tests: Tests that run multiple times with different sets of parameters.
 - @ParameterizedTest: Annotation used to denote a parameterized test.
 - @ValueSource: Annotation used to provide a single array of values to the parameterized test.
 - @CsvSource: Annotation used to provide multiple sets of values in CSV format.
 - @MethodSource: Annotation used to provide a method that returns a stream of arguments.
 
Step-by-Step Guide
- Adding Dependencies
 
First, ensure you have the necessary dependencies in your pom.xml (for Maven) or build.gradle (for Gradle) file.
Maven:
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.8.1</version>
    <scope>test</scope>
</dependency>Gradle:
- Creating a Simple Parameterized Test
 
Let's start with a simple example using @ValueSource.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ParameterizedTestExample {
    @ParameterizedTest
    @ValueSource(strings = {"racecar", "radar", "level"})
    void testPalindrome(String candidate) {
        assertTrue(isPalindrome(candidate));
    }
    boolean isPalindrome(String str) {
        return str.equals(new StringBuilder(str).reverse().toString());
    }
}Explanation:
@ParameterizedTestindicates that the method is a parameterized test.@ValueSource(strings = {"racecar", "radar", "level"})provides the parameters for the test.- The 
testPalindromemethod will run three times, once for each string in the@ValueSource. 
- Using @CsvSource for Multiple Parameters
 
If you need to pass multiple parameters, you can use @CsvSource.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CsvSourceExample {
    @ParameterizedTest
    @CsvSource({
        "1, 1, 2",
        "2, 3, 5",
        "3, 5, 8"
    })
    void testAddition(int a, int b, int expected) {
        assertEquals(expected, add(a, b));
    }
    int add(int a, int b) {
        return a + b;
    }
}Explanation:
@CsvSourceprovides multiple sets of parameters in CSV format.- The 
testAdditionmethod will run three times with different sets of parameters. 
- Using @MethodSource for Complex Parameters
 
For more complex scenarios, you can use @MethodSource to provide parameters from a method.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MethodSourceExample {
    @ParameterizedTest
    @MethodSource("provideStringsForIsBlank")
    void testIsBlank(String input, boolean expected) {
        assertEquals(expected, isBlank(input));
    }
    static Stream<Arguments> provideStringsForIsBlank() {
        return Stream.of(
            Arguments.of(null, true),
            Arguments.of("", true),
            Arguments.of("  ", true),
            Arguments.of("not blank", false)
        );
    }
    boolean isBlank(String str) {
        return str == null || str.trim().isEmpty();
    }
}Explanation:
@MethodSource("provideStringsForIsBlank")specifies the method that provides the parameters.- The 
provideStringsForIsBlankmethod returns a stream ofArguments. - The 
testIsBlankmethod will run four times with different sets of parameters. 
Practical Exercise
Exercise: Create a Parameterized Test for a Multiplication Function
- Create a method 
multiply(int a, int b)that returns the product ofaandb. - Write a parameterized test using 
@CsvSourceto test themultiplymethod with the following pairs of values:- (2, 3, 6)
 - (4, 5, 20)
 - (6, 7, 42)
 
 
Solution
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MultiplicationTest {
    @ParameterizedTest
    @CsvSource({
        "2, 3, 6",
        "4, 5, 20",
        "6, 7, 42"
    })
    void testMultiply(int a, int b, int expected) {
        assertEquals(expected, multiply(a, b));
    }
    int multiply(int a, int b) {
        return a * b;
    }
}Explanation:
- The 
@CsvSourceannotation provides the parameters for the test. - The 
testMultiplymethod will run three times with different sets of parameters. 
Conclusion
In this section, we learned how to create parameterized tests in JUnit using @ValueSource, @CsvSource, and @MethodSource. Parameterized tests are a powerful feature that allows you to run the same test with different inputs, making your tests more comprehensive and reducing code duplication. In the next section, we will explore the @ParameterizedTest annotation in more detail.
JUnit Course
Module 1: Introduction to JUnit
Module 2: Basic JUnit Annotations
- Understanding @Test
 - Using @Before and @After
 - Using @BeforeClass and @AfterClass
 - Ignoring Tests with @Ignore
 
Module 3: Assertions in JUnit
Module 4: Parameterized Tests
- Introduction to Parameterized Tests
 - Creating Parameterized Tests
 - Using @ParameterizedTest
 - Custom Parameterized Tests
 
Module 5: Test Suites
Module 6: Mocking with JUnit
Module 7: Advanced JUnit Features
Module 8: Best Practices and Tips
- Writing Effective Tests
 - Organizing Test Code
 - Test-Driven Development (TDD)
 - Continuous Integration with JUnit
 
