Skip to main content

How to do Parameterization in JMeter

How to do Parameterization in JMeter

Key takeaways

  • Parameterization means replacing a hardcoded value in a test plan with a ${variable} that JMeter fills in at run time, so each virtual user can send different data.
  • Pick the source by what the value is: CSV Data Set Config for per-user rows, __P for values you pass on the command line, User Defined Variables for constants, and __Random, __RandomString or __UUID for generated values.
  • A User Defined Variable that holds a function is evaluated once, so it cannot give each request a fresh value. Put the function in the request field itself.
  • Parameterization supplies data you know in advance. Values the server hands back, such as session tokens, need an extractor (correlation), which is a separate step.

Parameterization in JMeter is the practice of replacing fixed values in a test plan, such as a username, a product ID or a host name, with variables whose value is decided when the test runs. Without it every virtual user sends the identical request, which usually means you are measuring a cache rather than your application. This guide covers the five ways to feed a variable in JMeter 5.6.x, shows what each one does on a real run, and says which to use when.

What parameterization means in JMeter

JMeter reads ${name} in almost any field of any test element and replaces it with the value of the variable name for the current thread. It also reads ${__functionName(args)}, which calls a built-in function. The manual says functions and variables can be written into any field of any test component, with the exception that some numeric fields do not accept them and that functions on the Test Plan element itself have restrictions, because thread variables are not set up yet when they are processed (functions reference).

Each thread gets its own copy of the variables, so ${user} can be alice in thread 1 and bob in thread 2 at the same moment. That per-thread copy is what makes it possible to simulate different users from one script. How many users the script simulates at once is set in the Thread Group, covered in the ramp-up post.

Which method to use

You needUseValue changes
A different row per user or per iteration (logins, product IDs, search terms)CSV Data Set ConfigOn every iteration, per thread
A value you set per run from the command line (environment, host, user count)${__P(name,default)} or ${__property(name)}Never during the run
A constant used in many placesUser Defined Variables, or Test Plan variablesNever during the run
A small fixed list assigned to threads in orderUser Parameters pre-processorPer thread
A random number, string or unique ID__Random, __RandomString, __UUIDOn every call

CSV Data Set Config for per-user data

CSV Data Set Config reads a file line by line and splits each line into variables. By default the file is opened once and each thread takes a different line, but the manual notes that the order in which lines reach threads depends on the order in which threads execute, so you cannot rely on thread 1 always getting line 1. The three settings that matter most are Recycle on EOF, Stop thread on EOF and Sharing mode. If the file runs out and recycling is off, every variable is set to <EOF> (or the thread stops, if Stop thread is on). Leave Variable Names empty and JMeter takes the column names from the file’s header line.

I ran this on JMeter 5.6.3 with a 3-line users.csv (header user,pass), 3 threads and 2 loops against a local mock server. The six requests carried user=alice, bob and carol, each twice, spread across the threads. Because the file has three rows and the test makes six requests, recycling wrapped the file around once. Per the manual, with Recycle off and Stop thread on, a thread stops at the end of the file instead (I did not run that variant).

The full walk-through of every option, including per-thread files with ${__threadNum} and the sharing modes, is in How to Use CSV Data Set to Configure JMeter Tests and Using CSV Data in JMeter Tests. Use those rather than repeating the details here. One rule from the manual is worth stating: generating unique random values at run time costs CPU and memory, so prepare large sets of values in a file ahead of the test.

Values from the command line with __P

${__P(env,staging)} returns the JMeter property env, or staging if it is not set. Pass the property with -J:

jmeter -n -t plan.jmx -l results.jtl -Jenv=prod

__P is the shorthand meant for properties defined on the command line. It cannot store the value in a variable, and if you omit the default it returns 1, which the manual chose because it suits thread counts, loops and ramp-up. __property is the longer form: it can save the result in a variable, and if the property is missing and no default is given it returns the property name itself, which is a quiet way to send the wrong value. Always give a default.

This is how you make the thread count and ramp-up configurable: set the Thread Group fields to ${__P(threads,10)} and ${__P(ramp,60)}, then change them per run without opening the plan.

User Defined Variables and when they are evaluated

User Defined Variables (UDV) define an initial set of variables. The manual is specific about the timing: all UDV elements in a plan, wherever they sit, are processed at the start, so you cannot reference a variable that a post-processor sets during the run. They are processed top to bottom, the result is copied to each thread, and a runtime element such as a Regular Expression Extractor that defines a variable with the same name replaces the initial value for that thread.

The consequence is the trap most people hit. The manual says UDVs should not be used with functions that return a different result on each call, because only the result of the first call is saved. I tested it: a UDV runid set to ${__UUID()} produced the same ID (071af443-...) in all six requests, while ${__UUID()} typed directly into the request path produced six different ones. A UDV is the right place for ${__P(env,staging)}, since a property does not change mid-run. For anything that must differ per request, put the function in the sampler field.

User Parameters for a short list per thread

The User Parameters pre-processor gives each thread a value from a short list, in order, and reuses values when there are more threads than values. I gave it two values (gold, silver) and ran three threads: threads 1 and 3 got gold, thread 2 got silver. The manual itself points to CSV Data Set Config for larger sets. Reach for User Parameters only for a handful of fixed roles.

Random strings, numbers and unique IDs

Three functions cover most generated data, all current in 5.6.x:

  • ${__Random(1,100)} returns a number between the minimum and the maximum.
  • ${__RandomString(5,abcdef)} returns a string of the given length from the characters you list.
  • ${__UUID()} returns a random type 4 UUID.

On the test run they produced values such as n=87, s=acadc and a fresh UUID on each request. Use __UUID where the application demands a unique value, for example an order reference or an email local part. The post on generating dynamic IDs in JMeter goes deeper on this. For randomness that must be reproducible, use a CSV file instead.

Parameterization is not correlation

Parameterization feeds values you chose. Correlation takes a value out of a response and uses it in the next request, for example a session ID or CSRF token, with an extractor such as the Regular Expression Extractor or JSON Extractor. Both end in a ${variable}, which is why they get confused, but they solve different problems: data you know before the test versus data the server creates during it. The order in which JMeter runs pre-processors, samplers and extractors decides whether a variable exists when you use it; see the execution order of JMeter elements.

For the extraction side, correlation in JMeter works through a CSRF value, a bearer token and a list of IDs, with a run that shows what breaks when the extractors are missing.

Debugging a variable that does not resolve

When JMeter cannot resolve ${name} it sends the literal text ${name}. Three checks find most causes:

  • Name mismatch. Variable names are case sensitive. ${User} and ${user} are different variables.
  • Wrong CSV path. A relative file name resolves against the folder of the active test plan, and for distributed tests the file must exist at the same relative path on every load generator.
  • Scope and timing. A variable defined in a post-processor is not available to a UDV, and a UDV cannot reference a variable defined in the same element.

Add a Debug Sampler during scripting and look at it in View Results Tree, then disable both before the real run, because the manual advises against View Results Tree during load tests.

Running parameterized plans in the cloud

LoadFocus accepts standard .jmx files and, per its JMeter load testing page, lets you upload CSV data files with the plan, so a parameterized script runs from its cloud regions without changes. You set the virtual users, duration and ramp-up for the run in the browser. Plan limits on virtual users differ, so check the live page for the current numbers.

Frequently Asked Questions

How do I parameterize a JMeter script?

Replace each hardcoded value with a ${variable} and define that variable in the right place: a CSV Data Set Config for per-user rows, __P for command-line values, or a function such as __UUID for generated values. Then run a one-thread, one-loop test and check in View Results Tree that every field was substituted.

What is the difference between parameterization and correlation in JMeter?

Parameterization supplies data you prepared before the run. Correlation captures a value from a server response, such as a token, and reuses it in a later request. A realistic script usually needs both.

Why does my User Defined Variable return the same value every time?

UDVs are processed once, at the start of the test, and only the first call of a function is saved. Move the function call into the sampler field, or use a CSV file or a Random Variable config element.

Should I use CSV Data Set Config or User Parameters?

Use CSV Data Set Config for anything beyond a handful of values. The manual describes it as more suitable for large numbers of parameters. User Parameters suits a few fixed roles assigned to threads in order.

Which scripting language should I use for custom parameter logic?

Use a JSR223 element with Groovy. The manual recommends migrating BeanShell elements to JSR223 with Groovy for performance and support of new Java features. Built-in functions cover most needs, so script only when a function cannot do it. See which language JMeter uses.

Sources

Chris

Head of Content at LoadFocus

Chris leads content and oversees development across the services this blog covers. The guides and tool comparisons here come out of the same decisions that shape what ships.

Weekly tips right in your inbox.

Don’t miss out on the latest testing tips and tricks, tools and news related to software testing.

Already +20,000 members in the list.

The Load Testing Platform with AI That Explains Your Results

Load test websites and APIs from 25 cloud regions, monitor page speed and uptime, and get AI analysis that explains your results in plain English.

Cloud load testing, website speed and API monitoring in one place.

Hi there! Can I share a cool thing I'm working on with you?

A software testing newsletter that sparks joy.

Our goal is to create helpful content for software developers and testers.

If you're not into it, you can unsubscribe instantly.