If Controller: Conditional Execution
The If Controller executes its child elements only when a specified condition evaluates to true, letting a single test plan branch between different behaviors — for example, only submitting a coupon-code request if a JMeter variable ${hasCoupon} equals 'true'. The condition field accepts either JMeter's default syntax, which is a simple expression compared against JavaScript-like truthiness, or you can check 'Interpret Condition as Variable Expression' to evaluate it strictly as JavaScript via the Nashorn/Rhino-compatible engine, which supports proper boolean logic like ${count} > 5. Because the condition is re-evaluated on every loop iteration, it's commonly combined with variables extracted earlier in the same thread via a Regular Expression Extractor or JSON Extractor, letting the test plan react dynamically to what the server actually returned.
Cricket analogy: An If Controller gating a coupon-code request on ${hasCoupon} is like a captain's decision to review a dismissal with DRS only if the team still has reviews remaining — the review request (child samplers) only fires when the specific condition (reviews > 0) holds true.
Loop Controller: Repeating a Block
A Loop Controller repeats its child elements a specified number of times, or infinitely if you set the loop count to -1 (Forever), and it operates independently of the Thread Group's own loop count setting. This distinction matters: the Thread Group loop count repeats the entire test plan for a thread, while a Loop Controller lets you repeat just a sub-section — for example, looping an 'add item to cart' request three times to simulate a shopper adding multiple products before checking out once, without repeating the login and checkout steps three times as well. Nesting a Loop Controller inside a While Controller or combining it with counters via a Counter config element gives you fine-grained control over repetition patterns that a flat Thread Group loop count cannot express.
Cricket analogy: A Loop Controller repeating just the 'bowl a delivery' block three times within one over is like a bowler repeating their run-up and delivery action six times per over while the toss, innings break, and presentation ceremony happen only once per match — repetition is scoped to the right level.
Transaction Controller: Grouping Samplers into One Metric
A Transaction Controller wraps multiple samplers and reports their combined elapsed time as a single named 'transaction' sample in your results, which is essential when a real user action — like 'complete checkout' — actually involves several HTTP requests (submit shipping info, apply coupon, confirm payment) that you want measured and reported as one business-meaningful unit rather than three disconnected rows. Its 'Generate parent sample' checkbox controls whether the individual child samples are still shown separately (nested under the transaction in View Results Tree) or hidden entirely, with only the aggregated transaction result reported; enabling parent-sample generation keeps the detail available for debugging while still giving Aggregate Report a clean, business-level row to analyze.
Cricket analogy: A Transaction Controller combining several samplers into one metric is like reporting a completed bowling spell's total figures (overs, runs, wickets) as one summary line rather than listing every single delivery separately in the main scorecard, even though ball-by-ball detail like Bumrah's spell is still available if you dig into commentary.
<IfController guiclass="IfControllerPanel" testclass="IfController" testname="If Has Coupon">
<stringProp name="IfController.condition">${hasCoupon} == "true"</stringProp>
<boolProp name="IfController.evaluateAll">false</boolProp>
</IfController>
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Add 3 Items to Cart">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">3</stringProp>
</LoopController>
<TransactionController guiclass="TransactionControllerGui" testclass="TransactionController" testname="Complete Checkout">
<boolProp name="TransactionController.includeTimers">false</boolProp>
<boolProp name="TransactionController.parent">true</boolProp>
</TransactionController>The If Controller's 'Evaluate for all children' checkbox controls whether the condition is checked once per child or just once before entering the block; leaving it unchecked (evaluate once) is usually correct and slightly cheaper for blocks with many children.
A Loop Controller set to 'Forever' (-1) with no exit condition inside an otherwise finite Thread Group will run indefinitely for that thread, potentially preventing the test from ever completing. Always pair infinite loops with a duration-based Thread Group scheduler or an internal exit mechanism like a While Controller condition.
- If Controller executes its children only when its condition evaluates true, re-checked on every loop iteration.
- Use 'Interpret Condition as Variable Expression' for proper JavaScript-style boolean logic instead of the simpler default syntax.
- Loop Controller repeats just its child elements a fixed number of times (or Forever with -1), independent of the Thread Group's own loop count.
- Scoping repetition with a Loop Controller avoids re-running steps like login or checkout that should only happen once per thread.
- Transaction Controller reports multiple wrapped samplers' combined elapsed time as one named business-level transaction sample.
- 'Generate parent sample' keeps child sample detail available (nested in View Results Tree) while still producing one clean row for Aggregate Report.
- Infinite Loop Controllers need an explicit exit condition or a duration-based Thread Group scheduler to avoid hanging a test run.
Practice what you learned
1. What does JMeter's If Controller do with its child elements?
2. How does a Loop Controller's loop count differ from the Thread Group's own loop count setting?
3. What is the primary purpose of wrapping several samplers in a Transaction Controller?
4. What risk does setting a Loop Controller to 'Forever' (-1) introduce if left unmanaged?
Was this page helpful?
You May Also Like
Response Assertions
Learn how JMeter's Response Assertion element validates sample responses against text, regex, and status-code patterns so failures are caught automatically instead of hiding in raw response data.
Duration and Size Assertions
Use JMeter's Duration Assertion and Size Assertion elements to fail samples that violate response-time SLAs or return an unexpected payload size, catching performance and correctness regressions in the same test run.
Listeners: View Results Tree and Summary Report
Understand JMeter's two most-used listeners — View Results Tree for per-sample debugging and Summary Report for aggregate metrics — and how to use each without crippling your test's performance.