@CsvFileSource helps you run the same test many times with different data from a CSV file. This saves time and avoids repeating code.
@CsvFileSource for external CSV in JUnit
@ParameterizedTest @CsvFileSource(resources = "/data.csv", numLinesToSkip = 1) void testMethod(String input, int expected) { // test code here }
resources points to the CSV file path inside your test resources folder.
numLinesToSkip is used to skip header lines in the CSV file.
@ParameterizedTest @CsvFileSource(resources = "/numbers.csv") void testWithNumbers(int number) { assertTrue(number > 0); }
@ParameterizedTest @CsvFileSource(resources = "/users.csv", numLinesToSkip = 1) void testUserLogin(String username, String password) { assertNotNull(username); assertNotNull(password); }
This test reads three numbers per line from test-data.csv (skipping the header). It checks if the sum of a and b equals expectedSum.
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvFileSource; public class CsvFileSourceTest { @ParameterizedTest @CsvFileSource(resources = "/test-data.csv", numLinesToSkip = 1) void testSum(int a, int b, int expectedSum) { int actualSum = a + b; assertEquals(expectedSum, actualSum); } }
Place your CSV file in src/test/resources folder so it is on the test classpath.
Use forward slashes '/' in the resource path, even on Windows.
Make sure the CSV file encoding is UTF-8 to avoid reading errors.
@CsvFileSource lets you run parameterized tests with data from CSV files.
It helps keep test data separate and easy to update.
Remember to skip headers if your CSV has them using numLinesToSkip.
Practice
@CsvFileSource in JUnit tests?Solution
Step 1: Understand the role of @CsvFileSource
@CsvFileSource provides external CSV data to parameterized tests, allowing multiple runs with different inputs.Step 2: Compare options with this role
Only To run the same test multiple times with different data from a CSV file correctly describes running tests multiple times with CSV data. Others describe unrelated actions.Final Answer:
To run the same test multiple times with different data from a CSV file -> Option AQuick Check:
@CsvFileSource runs tests with CSV data = B [OK]
- Thinking @CsvFileSource writes data instead of reading
- Confusing it with random data generation
- Assuming it controls test skipping
@CsvFileSource?Solution
Step 1: Recall the correct attribute for skipping lines
The correct attribute to skip lines in @CsvFileSource isnumLinesToSkip.Step 2: Match options with correct attribute
Only @CsvFileSource(resources = "/data.csv", numLinesToSkip = 1) usesnumLinesToSkip = 1which skips the first line (header).Final Answer:
@CsvFileSource(resources = "/data.csv", numLinesToSkip = 1) -> Option DQuick Check:
Skip header line = numLinesToSkip = 1 [OK]
- Using non-existent attributes like skipHeader or ignoreFirstLine
- Confusing skipLines with numLinesToSkip
- Forgetting to skip header causing test failures
data.csv with content:name,age Alice,30 Bob,25
and the test method:
@ParameterizedTest
@CsvFileSource(resources = "/data.csv", numLinesToSkip = 1)
void testUser(String name, int age) {
System.out.println(name + "-" + age);
}What will be the printed output when the test runs?
Solution
Step 1: Understand numLinesToSkip effect
numLinesToSkip=1 skips the header line "name,age" so only data lines remain.Step 2: Identify printed lines
Test runs twice, printing "Alice-30" and "Bob-25" each on separate lines.Final Answer:
Alice-30 Bob-25 -> Option BQuick Check:
Header skipped, prints data lines only = D [OK]
- Not skipping header causing it to print as data
- Expecting header line to print
- Confusing output format with CSV file content
@ParameterizedTest
@CsvFileSource(resources = "/users.csv")
void testUser(String name, int age) {
assertTrue(age > 0);
}The CSV file
users.csv has a header line. What is the likely problem when running this test?Solution
Step 1: Check if header is skipped
NonumLinesToSkipis set, so header line is treated as data.Step 2: Understand impact on parsing
Trying to convert header "age" to int causes NumberFormatException, failing the test.Final Answer:
Test will fail because header line is treated as data causing NumberFormatException -> Option AQuick Check:
Header not skipped causes parse error = A [OK]
- Assuming header is skipped automatically
- Forgetting to add numLinesToSkip=1
- Confusing @ParameterizedTest with @Test
product,price,discountRate. The CSV has a header line. Which is the best way to write the parameterized test method signature and annotation to correctly read and use this data?Solution
Step 1: Identify header skipping attribute
UsenumLinesToSkip = 1to skip the CSV header line.Step 2: Match method parameters to CSV columns and types
Product is String, price and discountRate are decimal numbers, so usedoublefor price and discountRate.Step 3: Check options for correctness
@ParameterizedTest @CsvFileSource(resources = "/discounts.csv", numLinesToSkip = 1) void testDiscount(String product, double price, double discountRate) { ... } correctly usesnumLinesToSkip=1and matching parameter types. @ParameterizedTest @CsvFileSource(resources = "/discounts.csv") void testDiscount(String product, int price, int discountRate) { ... } misses skipping header and uses int instead of double. @ParameterizedTest @CsvFileSource(resources = "/discounts.csv", numLinesToSkip = 1) void testDiscount(String product, String price, String discountRate) { ... } uses String for numeric fields. @ParameterizedTest @CsvFileSource(resources = "/discounts.csv", skipHeader = true) void testDiscount(String product, double price, double discountRate) { ... } uses invalid attributeskipHeader.Final Answer:
@ParameterizedTest @CsvFileSource(resources = "/discounts.csv", numLinesToSkip = 1) void testDiscount(String product, double price, double discountRate) { ... } -> Option CQuick Check:
Skip header with numLinesToSkip=1 and match types = C [OK]
- Using skipHeader instead of numLinesToSkip
- Not skipping header causing parse errors
- Mismatching parameter types with CSV data
Ready to prove it?
Pass the test and this pattern moves unknown
