skip to content

In JMeter, ${A${N}} does not resolve. How do you look up a variable whose name is built at run time?

level: middleimportance: should knowfreq 48%

answer

  1. The parser stops at the first closing brace
  2. One function takes a name, not a value
  3. Arguments follow different rules than fields
  4. A miss can look like a value

basics

~10 s

JMeter has no nested-variable syntax. Wrap the composed name in the __V function instead: ${__V(A${N})} evaluates A${N} to A1 first, then returns the value of the variable called A1.

solid answer

~40 s

Plain `${A${N}}` fails because JMeter closes a reference at the first `}` it meets, so the name it looks up is `A${N` — no such variable, and the whole text comes back unchanged. Inside a *function argument* the rules differ: the parser tracks `${` and `}` depth, so a nested reference is compiled as a value in its own right. That is what `${__V(A${N})}` exploits — `A${N}` resolves to `A1`, and `__V` then looks up `A1`. `__V` takes the name plus an optional default; with no default and no such variable it returns the composed **name**, not a blank. Its neighbours do different jobs: `__evalVar(NAME)` resolves references inside the *value* of `NAME`, and `__eval(TEXT)` resolves references inside text you supply. Apache JMeter 6.0.0.

code

text · 7 lines
text
# Variables in scope: N=2, A1=alpha, A2=beta

${A${N}}          -> ${A${N}}      (literal text, no error)
${__V(A${N})}     -> beta
${__V(A${N},??)}  -> beta
${__V(B${N})}     -> B2            (the composed name, because B2 is unset)
${__V(B${N},??)}  -> ??

go deeper

for a junior

Know that JMeter cannot nest one ${} inside another as a variable name, and that __V is the function that does it. Recognise ${__V(A${N})} when you meet it in someone else's plan.

for a middle

Explain why argument lists allow nesting while bare references do not: the parser counts brace depth inside an argument but closes a bare reference at the first brace it sees.

for a senior

Show that you defend against the silent miss — a __V with no default returns the composed name, which reads like data. Say how you would catch that in a run rather than in review.

for a principal

Judge when a composed name is genuinely warranted against a flatter design: a lookup keyed by environment or locale is often better expressed as one variable set per environment than as name arithmetic in every field.

## Why ${A${N}} does not work JMeter's parser closes a reference at the **first** `}` it meets. Reading `${A${N}}` it takes `A${N` as the name, finds neither a function nor a variable called that, and hands the text back unchanged; the trailing `}` is ordinary text. The field ends up holding the literal `${A${N}}`. There is no nested-variable syntax in the reference form itself, and there never has been. ## __V evaluates a composed name `${__V(A${N})}` works, because the rules change inside an argument list. There the parser counts `${` and `}` depth, so `A${N}` is compiled as a value in its own right: it evaluates to `A1`, and only then is that string handed to `__V`, which looks up the variable named `A1`. ``` ${__V(A${N})} with N=1 -> the value of A1 ${__V(PRICE_${TIER})} with TIER=gold -> the value of PRICE_gold ${__V(NAME_${__counter(TRUE,)})} -> NAME_1, NAME_2, ... per iteration ``` ## What __V returns when the variable is missing `__V` accepts one or two arguments: 1. the variable name to evaluate — required; 2. a default value — optional. If the composed variable does not exist and you supplied a default, you get the default. If you supplied no default, **you get the composed name back**: `${__V(A${N})}` with no `A1` defined returns the two characters `A1`, not an empty string and not an error. That is the shape of the bug people chase for an hour — a plausible-looking value that is really the key the lookup failed to find. When the value matters, pass a default you would recognise on sight. ## __V, __evalVar and __eval do three different jobs | Call | What you pass it | What comes back | | --- | --- | --- | | `${__V(NAME)}` | a variable **name**, possibly assembled from other references | the value of that variable | | `${__evalVar(NAME)}` | the **name** of a variable whose value contains references | that value with its references resolved | | `${__eval(TEXT)}` | a **string** containing references | the same string with its references resolved | Worked example from the manual: if `query` holds `select ${column} from ${table}`, and `column` and `table` hold `name` and `customers`, then `${__evalVar(query)}` returns `select name from customers`. `__eval` does the same for text you hand it directly, so `${__eval(${SQL})}` interpolates whatever `SQL` currently contains. `__evalVar` takes exactly one argument; `__V` takes one or two. ## Nesting is general, not a special case for __V Any argument of any function may contain a whole reference, to any depth: ``` ${__urlencode(${__V(LABEL_${LANG})})} ${__P(${__V(HOST_KEY_${ENV})},localhost)} ``` Two rules follow from the depth counting: - The inner reference is evaluated first, on every execution of the outer call. - A comma inside the inner `${...}` belongs to the inner call and must **not** be escaped — escaping it pushes a literal backslash into the inner argument and breaks that call instead. ## When to reach for it Composed names earn their place when the name itself is data: a per-environment host key, a per-locale label set, or the numbered variables a post-processor creates when it is asked for every match (`NAME_1`, `NAME_2`, alongside `NAME_matchNr`). Where the name is fixed, plain `${NAME}` is clearer and one evaluation cheaper. Reviewers should treat a composed name with no default as a question, not a style choice. Behaviour described is Apache JMeter 6.0.0.

  • What is the difference between __V and __evalVar in JMeter?
    `__V` takes a variable *name* and returns that variable's value, which lets you assemble the name from other references. `__evalVar` takes the name of a variable whose *value* contains references, and returns that value with the references resolved — the tool for a template stored in a variable or read from a file.
  • Why is a __V miss more dangerous than a missing plain variable reference?
    A plain `${A1}` miss leaves the obviously-broken text `${A1}` in the field. `${__V(A${N})}` with no default returns the bare composed name `A1`, which looks like a real value and will happily be sent as one. Always pass a default you would recognise, or assert on the result.

It is the difference between asking a cloakroom attendant for locker A1 and asking for the locker whose label you are about to work out. ${A${N}} hands over a label that still has a placeholder in it; ${__V(A${N})} works the label out first, then asks.

saying these in an interview costs you the question

  • Claims ${A${N}} resolves if the inner variable is defined first
  • Thinks a failed __V lookup returns an empty string
  • Escapes commas inside a nested function reference
  • Confuses __V with __evalVar when the value holds the references
  • Says nesting only works one level deep