How do I use @CsvFileSource to load test data from a file?

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, usually src/test/resources.
  • The leading / means the path is absolute from the classpath root.
  • numLinesToSkip = 1 skips 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.
  • NIL is explicitly converted to null.

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.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.