The CSV Data Set Config is the workhorse of parameterization in JMeter. It reads a CSV file row by row and assigns each column to a JMeter variable. Think of it as a data feeder -- every time a thread starts a new iteration, it grabs the next row from the file. Let me walk you through every setting because the defaults will bite you.
username,password,expected_name,account_type
priya.sharma@test.com,Priya@123,Priya Sharma,premium
rahul.kumar@test.com,Rahul@456,Rahul Kumar,standard
aneeta.singh@test.com,Aneeta@789,Aneeta Singh,premium
vikas.jain@test.com,Vikas@012,Vikas Jain,standard
meera.patel@test.com,Meera@345,Meera Patel,premium
amit.verma@test.com,Amit@678,Amit Verma,standard
neha.gupta@test.com,Neha@901,Neha Gupta,premium
rohit.malhotra@test.com,Rohit@234,Rohit Malhotra,standard
kavita.nair@test.com,Kavita@567,Kavita Nair,premium
sandeep.reddy@test.com,Sandeep@890,Sandeep Reddy,standardCSV file rules: (1) No spaces after commas unless they are part of the data. (2) No BOM (Byte Order Mark) -- save as UTF-8 without BOM. (3) No trailing newline at the end. (4) Keep the file in your JMeter test plan directory or use absolute paths. (5) On Windows, use forward slashes (/) or double backslashes (\\) in the path.
| Setting | What It Does | Recommended Value | Why |
|---|---|---|---|
| Filename | Path to the CSV file | test-data/users.csv (relative to JMX) | Relative paths make the test portable across machines |
| File Encoding | Character encoding | UTF-8 | Handles international characters correctly |
| Variable Names | Comma-separated variable names for each column | username,password,expected_name,account_type | Must match column count. If blank, uses first row as headers |
| Ignore first line | Skip the header row | True (if first row has headers) | Prevents headers from being used as data on first iteration |
| Delimiter | Column separator | , (comma) | Use \t for tab-separated files |
| Allow quoted data | Handle values with commas inside quotes | True | Needed if values contain the delimiter character |
| Recycle on EOF | Restart from beginning when file ends | True | False = thread stops when it runs out of data |
| Stop thread on EOF | Stop the thread when file ends | False | Only set True if each user should process exactly one row |
| Sharing mode | How threads share the file | All threads (most common) | See detailed explanation below |
Sharing mode controls which threads get which rows. This is the setting that causes the most confusion and bugs in parameterized tests. Let me explain with a concrete example: 3 thread groups, 2 threads each, CSV file with 6 rows.
| Sharing Mode | Behavior | Thread Group 1 (T1, T2) | Thread Group 2 (T3, T4) | Use Case |
|---|---|---|---|---|
| All threads | All threads in all groups share one file pointer | T1: Row1, T2: Row2 | T3: Row3, T4: Row4 | Each thread gets a unique row (most common for login tests) |
| Current thread group | Each thread group gets its own file pointer | T1: Row1, T2: Row2 | T3: Row1, T4: Row2 | Same data across groups but unique within group |
| Current thread | Each thread gets its own file pointer | T1: Row1 then Row2, T2: Row1 then Row2 | T3: Row1 then Row2, T4: Row1 then Row2 | Each thread iterates through ALL rows (good for data completeness) |
<!-- Add this under Thread Group, BEFORE the login request -->
<CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet"
testname="User Credentials" enabled="true">
<stringProp name="delimiter">,</stringProp>
<stringProp name="fileEncoding">UTF-8</stringProp>
<stringProp name="filename">test-data/users.csv</stringProp>
<boolProp name="ignoreFirstLine">true</boolProp>
<boolProp name="quotedData">true</boolProp>
<boolProp name="recycle">true</boolProp>
<stringProp name="shareMode">shareMode.all</stringProp>
<boolProp name="stopThread">false</boolProp>
<stringProp name="variableNames">username,password,expected_name,account_type</stringProp>
</CSVDataSet># HTTP Request: POST /api/login
# Body (JSON):
{
"username": "${username}",
"password": "${password}"
}
# Response Assertion (to verify correct user logged in):
# Pattern: ${expected_name}
# Conditional logic based on account type:
# If Controller: "${account_type}" == "premium"
# -> GET /api/premium/dashboard
# Else
# -> GET /api/standard/dashboardThis is a question I get asked all the time. The answer depends on your sharing mode and test requirements.
Real tests often need multiple data sources. You might have one CSV for user credentials, another for product IDs, and a third for shipping addresses. Just add multiple CSV Data Set Config elements. They are independent -- each has its own file pointer and sharing mode.
Thread Group (100 threads)
├── CSV Data Set Config: users.csv (username, password)
├── CSV Data Set Config: products.csv (product_id, product_name, quantity)
├── CSV Data Set Config: addresses.csv (street, city, zip, country)
├── Login Request -> uses ${username}, ${password}
├── Browse Product Request -> uses ${product_id}
├── Add to Cart Request -> uses ${product_id}, ${quantity}
└── Checkout Request -> uses ${street}, ${city}, ${zip}, ${country}
# Each CSV advances independently!
# Thread 1, Iteration 1: user1, product_A, address_X
# Thread 1, Iteration 2: user1, product_B, address_Y (user stays if sharing = current thread)
# Thread 2, Iteration 1: user2, product_C, address_ZWhen you have related data (like a user and their specific orders), keep them in the same CSV file. Only use separate CSV files for unrelated data sets. Otherwise, you get random combinations -- user1 with user2's shipping address -- which might cause assertion failures or incorrect test scenarios.
Q: How does the Sharing Mode in CSV Data Set Config affect thread behavior, and when would you use each mode?
A: Sharing Mode controls how threads share the CSV file pointer. "All threads" mode means all threads across all thread groups share a single file pointer -- each thread gets the next unique row. This is best for login tests where each virtual user needs unique credentials. "Current thread group" mode gives each thread group its own file pointer, so different groups can read the same data independently -- useful when you want both a buyer and seller group to use the same user pool. "Current thread" mode gives each thread its own file pointer, so every thread reads the entire file from the beginning -- useful when you want each virtual user to iterate through all test data (like testing all products per user).
Key Point: CSV Data Set Config reads rows sequentially and assigns columns to variables. The Sharing Mode setting is critical -- "All threads" gives each thread a unique row, which is what you want for login parameterization.