Use JUnit 5’s @CsvFileSource with a parameterized test to load rows from a CSV file and pass each row into your test method.
1. Add the CSV file
Place the CSV file under src/test/resources, for example:
src/test/resources/test-data/users.csv
Example CSV:
username,age,active
alice,30,true
bob,25,false
charlie,40,true
2. Use @CsvFileSource
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
class UserCsvTest {
@ParameterizedTest
@CsvFileSource(
resources = "/test-data/users.csv",
numLinesToSkip = 1
)
void loadsUsersFromCsv(String username, int age, boolean active) {
assertNotNull(username);
assertTrue(age > 0);
System.out.println(username + " " + age + " " + active);
}
}
Key points
resources = "/test-data/users.csv"loads the file from the test classpath, usuallysrc/test/resources.- The leading
/means the path is absolute from the classpath root. numLinesToSkip = 1skips the header row.- Each CSV column maps to a test method parameter.
- JUnit automatically converts common types like
String,int,boolean,double, enums, etc.
CSV with custom delimiter
If your file uses semicolons:
username;age;active
alice;30;true
bob;25;false
Use:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
class UserCsvTest {
@ParameterizedTest
@CsvFileSource(
resources = "/test-data/users.csv",
numLinesToSkip = 1,
delimiter = ';'
)
void loadsUsersFromCsv(String username, int age, boolean active) {
// test logic
}
}
Loading from a filesystem path
If the file is not on the classpath, use files instead of resources:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
class ExternalCsvTest {
@ParameterizedTest
@CsvFileSource(
files = "src/test/resources/test-data/users.csv",
numLinesToSkip = 1
)
void loadsUsersFromFile(String username, int age, boolean active) {
// test logic
}
}
Handling empty and null values
Example CSV:
name,email
Alice,[email protected]
Bob,
Charlie,NIL
Example test:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import static org.junit.jupiter.api.Assertions.assertNull;
class NullCsvTest {
@ParameterizedTest
@CsvFileSource(
resources = "/test-data/users.csv",
numLinesToSkip = 1,
nullValues = "NIL"
)
void handlesNullValues(String name, String email) {
if ("Charlie".equals(name)) {
assertNull(email);
}
}
}
In this example:
- Empty value after
Bob,is treated as an empty string by default in many CSV cases. NILis explicitly converted tonull.
Required dependency
For Maven, make sure you have junit-jupiter-params:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
With Spring Boot tests, this is often already included through spring-boot-starter-test.
