Parameterized Tests

One Test, Many Inputs

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;

class ValidatorTest {

    @ParameterizedTest
    @ValueSource(strings = {"9876543210", "6000000000"})
    void validMobileNumbers(String number) {
        assertTrue(Validator.isIndianMobile(number));
    }

    @ParameterizedTest
    @NullAndEmptySource
    @ValueSource(strings = {"12345", "5876543210", "98765abcde"})
    void invalidMobileNumbers(String number) {
        assertFalse(Validator.isIndianMobile(number));
    }

    @ParameterizedTest(name = "{0} kg costs Rs {1}")
    @CsvSource({
            "0.5, 40",
            "2,   60",
            "10,  140"
    })
    void shippingCost(double kg, int expected) {
        assertEquals(expected, Shipping.cost(kg));
    }

    @ParameterizedTest
    @MethodSource("coupons")
    void couponDiscount(String code, int cart, int expected) {
        assertEquals(expected, Coupons.apply(code, cart));
    }

    static Stream<Arguments> coupons() {
        return Stream.of(Arguments.of("SAVE10", 1000, 900), Arguments.of("FLAT50", 300, 250));
    }
}

Example

mvn test -Dtest=ValidatorTest

Example output

[INFO] Running com.shop.ValidatorTest
[INFO] Tests run: 12, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.087 s

Sources

AnnotationProvides
@ValueSourceone literal per run (strings, ints...)
@CsvSource, @CsvFileSourceseveral arguments per row
@EnumSourceeach enum constant
@MethodSourcea static method returning Stream<Arguments>
@NullSource, @EmptySourcenull / empty value