Chapter 10: Practice: Load Test a Web App
Here is something I see in almost every performance test review: all 100 virtual users log in as "testuser1" and search for "laptop." That is not a load test -- that is a DDoS simulation of the world's most boring customer. Real users have different accounts, search for different products, have different cart contents. Parameterization makes your test realistic.
You need at least as many test users as your maximum concurrent user count. If you plan to test with 250 users in the stress test, create 250 test accounts. Here is the format:
username,password
testuser001,Test@123
testuser002,Test@123
testuser003,Test@123
testuser004,Test@123
testuser005,Test@123
testuser006,Test@123
testuser007,Test@123
testuser008,Test@123
testuser009,Test@123
testuser010,Test@123
testuser011,Test@123
testuser012,Test@123
testuser013,Test@123
testuser014,Test@123
testuser015,Test@123
... (continue to testuser250)Pro tip: generate your CSV with a simple script instead of typing 250 rows by hand. In bash: for i in $(seq -w 1 250); do echo "testuser$i,Test@123"; done > test-data/users.csv. Or use JMeter's built-in __counter function if you do not need pre-created accounts.
Use a variety of search terms that match products in your application. Include terms with different result counts -- some that return many products, some that return few, and one or two that return zero results (because real users misspell things).
searchTerm
laptop
headphones
keyboard
mouse
monitor
tablet
phone
camera
printer
router
speaker
charger
case
stand
xyznoexistThe CSV Data Set Config element has several important settings. Getting these wrong leads to subtle but devastating test issues.
| Setting | Value for Users CSV | Value for Search CSV | Why |
|---|---|---|---|
| Variable Names | username,password | searchTerm | Maps CSV columns to JMeter variables |
| Delimiter | , | , | Comma-separated values |
| Recycle on EOF | true | true | When all rows are used, start from the beginning |
| Stop thread on EOF | false | false | Do not stop threads when CSV ends |
| Sharing mode | All threads | All threads | Each thread gets the next row sequentially |
| Allow quoted data | false | false | Set to true only if your data contains commas |
Sharing mode controls how CSV rows are distributed across threads. This is critical for the users CSV because you do NOT want two threads using the same username simultaneously -- that creates concurrent sessions for the same user, which is unrealistic and can cause server-side conflicts.
If your users CSV has fewer rows than your thread count, users will be recycled and multiple threads will share the same credentials. This can cause authentication conflicts and false failures. Always ensure: number of CSV rows >= max thread count.
Q: How do you handle test data in performance testing? How do you ensure each virtual user has unique data?
A: I use JMeter's CSV Data Set Config to feed unique data to each virtual user. I create CSV files for user credentials, search terms, and other variable data. The key is setting the sharing mode correctly -- for user credentials, I use "All threads" mode so each thread gets a unique row, preventing concurrent session conflicts. I ensure the CSV has at least as many rows as my maximum thread count. For data that does not need to be unique (like search terms), I use recycling so the limited set of terms gets reused. I also use JMeter functions like __counter and __RandomString for generating unique data on-the-fly when CSV files are impractical.
Key Point: Parameterization makes your test realistic. Use CSV files for credentials and search terms. Always ensure your user CSV has enough unique rows for your maximum thread count.
Key Point: Every virtual user needs unique data. CSV Data Set Config distributes rows across threads, but you must ensure enough rows exist and sharing mode is set correctly.