Parameterized Tests with @CsvSource and @MethodSource
Run the same test with multiple input sets using @ParameterizedTest, @CsvSource, and @MethodSource.
Parameterized Tests with @CsvSource and @MethodSource is a free Java Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Parameterized Tests?
Running the same test logic with multiple input sets reveals edge cases without copy-pasting test methods. JUnit 5 supports parameterized tests natively with @ParameterizedTest.
@ValueSource: Simple Single-Value Tests
@ValueSource provides a single parameter of a given type. The test runs once per value.
@ParameterizedTest
@ValueSource(strings = {"", " ", "\t"})
void blank_strings_are_rejected(String input) {
assertThrows(IllegalArgumentException.class, () -> validator.validate(input));
}@CsvSource: Multiple Parameters Inline
@CsvSource provides rows of comma-separated values. Each row is one test invocation. Use single quotes to escape commas in string values.
@ParameterizedTest
@CsvSource({
"Alice, 30, true",
"Bob, 17, false",
"Carol, 0, false"
})
void test_adult_check(String name, int age, boolean expectedAdult) {
User user = new User(name, age);
assertEquals(expectedAdult, user.isAdult());
}@CsvSource with delimiterString
Use delimiterString for multi-character delimiters or when your data contains commas. Use nullValues to map a sentinel string to null.
@ParameterizedTest
@CsvSource(value = {
"Alice | 30 | ADMIN",
"Bob | 25 | USER"
}, delimiterString = "|")
void test_roles(String name, int age, String role) { ... }@CsvFileSource: External Data Files
Load test data from a CSV file in the classpath. Useful for large datasets that would clutter the test code.
@ParameterizedTest
@CsvFileSource(resources = "/test-data/users.csv", numLinesToSkip = 1)
void test_from_file(String name, int age, boolean expected) {
assertEquals(expected, service.isEligible(name, age));
}@MethodSource: Complex Parameters
@MethodSource calls a static factory method that returns a Stream<Arguments>. Each Arguments.of() is one test invocation. Use for complex objects.
@ParameterizedTest
@MethodSource("provideOrders")
void test_total_calculation(Order order, BigDecimal expected) {
assertEquals(expected, orderService.calculateTotal(order));
}
static Stream<Arguments> provideOrders() {
return Stream.of(
Arguments.of(new Order(List.of(item(10), item(20))), BigDecimal.valueOf(30)),
Arguments.of(new Order(List.of()), BigDecimal.ZERO)
);
}@EnumSource: Testing All Enum Values
@EnumSource runs the test once for each enum constant. Use mode and names to include or exclude specific values.
@ParameterizedTest
@EnumSource(value = UserStatus.class, mode = EnumSource.Mode.EXCLUDE, names = "DELETED")
void test_active_statuses(UserStatus status) {
assertTrue(notificationService.shouldNotify(status));
}@NullAndEmptySource
Shorthand for testing null and empty string inputs. Combine with @ValueSource using @NullSource + @EmptySource or the combined @NullAndEmptySource.
@ParameterizedTest
@NullAndEmptySource
void null_and_empty_are_invalid(String input) {
assertFalse(validator.isValid(input));
}Custom Display Names
Use name in @ParameterizedTest to format the test display name. Placeholders: {index}, {0}, {1}, {arguments}.
@ParameterizedTest(name = "age={1} should be adult={2}")
@CsvSource({"Alice, 30, true", "Bob, 17, false"})
void test_adult(String name, int age, boolean expected) { ... }Combining Sources with @ArgumentsSource
Implement ArgumentsProvider for fully custom argument generation — dynamic data from databases, files, or APIs.
public class UserArgumentsProvider implements ArgumentsProvider {
public Stream<? extends Arguments> provideArguments(ExtensionContext ctx) {
return Stream.of(
Arguments.of(new User("Alice", 30)),
Arguments.of(new User("Bob", 17))
);
}
}
@ParameterizedTest
@ArgumentsSource(UserArgumentsProvider.class)
void test_user(User user) { ... }Parameterized Tests for Boundary Values
Systematically test boundary conditions: min-1, min, max, max+1. Parameterized tests make boundary coverage readable and maintainable.
@ParameterizedTest
@CsvSource({"0, false", "1, true", "100, true", "101, false"})
void test_range_boundaries(int value, boolean expected) {
assertEquals(expected, validator.isInRange(value, 1, 100));
}Quick Check
Which @MethodSource returns type provides each test invocation's arguments?
Recap
Use @CsvSource for inline tabular data, @MethodSource for complex objects, @EnumSource for all enum values, and @NullAndEmptySource for null/empty edge cases. Custom names with name= improve test readability.
Frequently asked questions
Is the “Parameterized Tests with @CsvSource and @MethodSource” lesson free?
Yes — the full text of “Parameterized Tests with @CsvSource and @MethodSource” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Parameterized Tests with @CsvSource and @MethodSource”?
Run the same test with multiple input sets using @ParameterizedTest, @CsvSource, and @MethodSource. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Parameterized Tests with @CsvSource and @MethodSource” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Parameterized Tests with @CsvSource and @MethodSource
- Mockito Advanced: Argument Captors and Spies
- Spring Boot Test Slices: @WebMvcTest and @DataJpaTest
- Testcontainers: Real Database Integration Tests