@CsvFileSource for external CSV in JUnit - Build an Automation Script
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvFileSource; import static org.junit.jupiter.api.Assertions.assertEquals; public class CsvFileSourceTest { @ParameterizedTest @CsvFileSource(resources = "/test-data.csv", numLinesToSkip = 1) void testStringLength(String input, int expectedLength) { assertEquals(expectedLength, input.length(), () -> "Expected length " + expectedLength + " but got " + input.length() + " for input: '" + input + "'"); } }
The test class CsvFileSourceTest uses JUnit 5's @ParameterizedTest to run the test method multiple times with different inputs.
The @CsvFileSource annotation loads data from the external CSV file test-data.csv located in src/test/resources. The resources path starts with a slash to indicate classpath root.
numLinesToSkip = 1 skips the header row in the CSV file.
The test method testStringLength receives two parameters: the input string and the expected length from each CSV row.
Inside the method, assertEquals checks if the actual string length matches the expected length, with a clear message to help debug if it fails.
This approach keeps tests clean, readable, and easy to maintain.
Extend the test to also verify that the input string is not empty for each CSV row
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
