skip to content

Standardising a JMeter plan skeleton across several teams, which element families would you mandate and why?

level: principalimportance: should knowfreq 28%

answer

  1. Start from what the engine requires
  2. Phases before families
  3. Some families are authoring tools only
  4. Mandate the skeleton, not the numbers

basics

~20 s

Mandate the phase shape and the family placement, not the numbers: a setUp group for preparation, one measured Thread Group per journey, a tearDown group for cleanup, plan-level config elements, one agreed result listener, and no Non-Test Elements committed.

solid answer

~50 s

A house skeleton is worth having because JMeter's families already carry meaning, and a shared placement makes any plan readable at a glance. What is genuinely worth fixing: **which phase** work lives in — preparation in a setUp Thread Group, the measured journeys in regular Thread Groups, cleanup in a tearDown Thread Group with *Run tearDown Thread Groups after shutdown of main threads* ticked; **where config elements hang** — plan-level defaults and managers so a plan retargets by editing one node; **which listener is the result of record**, so runs are comparable; and **what is banned** — Non-Test Elements such as the HTTP(S) Test Script Recorder left in a committed plan, and Functional Test Mode left ticked. What is not worth mandating is thread counts, loops or timer values: those belong to whoever owns the workload. The skeleton fixes structure; the team fixes load.

go deeper

for a junior

You are not expected to set the convention, but you should be able to follow one: put preparation in a setUp group, the journey in a Thread Group, cleanup in a tearDown group, and leave Functional Test Mode off.

for a middle

Explain why each placement follows from the engine's behaviour rather than from taste, especially why preparation belongs in a setUp phase instead of a Once Only Controller inside the measured group.

for a senior

Bring the failure modes you have seen: cleanup skipped on a cancelled run, a recorder committed with a plan, a debugging checkbox left ticked before an overnight run. Those are what the skeleton is defending against.

for a principal

Own the line between structure and workload, say where it moves and why, and name the enforcement mechanism. A convention that cannot be checked mechanically or in review is a preference with better branding.

## What a skeleton is for A JMeter plan is a tree, and the same intent can be expressed in several structurally different trees. Left alone, every team invents its own arrangement, and reviewing another team's plan becomes an archaeology exercise. A house skeleton is a decision about **which family owns which kind of work**, so that any reviewer can read an unfamiliar plan family by family and know immediately what it does. The trap is mandating the wrong layer. Numbers — threads, loops, ramp, timer values — are workload decisions that belong to whoever owns the service. Structure is a review decision, and that is what a skeleton should fix. ## What is worth mandating | Decision | Why it is a structural call | | --- | --- | | Preparation lives in a **setUp Thread Group** | The engine runs that phase to completion before any regular group starts, so anything the load depends on is guaranteed ready. A Once Only Controller would run per thread instead. | | One **Thread Group** per user journey | Makes the plan's journeys countable without opening panels, and keeps result labels attributable. | | Cleanup in a **tearDown Thread Group**, with the Test Plan's shutdown option ticked | `TestPlan.tearDown_on_shutdown` defaults to false, so cleanup silently vanishes on an early shutdown unless the box is set. | | Plan-level **Config Elements** for defaults and managers | Retargeting a plan at another environment becomes editing one node instead of every sampler. | | One agreed **Listener** as the result of record | Every listener saves the same data and differs only in presentation, so the argument is about which file the pipeline reads, not about which chart is nicer. | | **Non-Test Elements** stripped before commit | The HTTP(S) Test Script Recorder and HTTP Mirror Server are authoring tools; a committed plan that still contains one is a plan someone left mid-capture. | | **Functional Test Mode off** in any committed plan | It overrides every listener's save configuration and is a debugging aid, not a run setting. | ## What to leave to the teams - Thread counts, loop counts, ramp and scheduler settings. - Which timers, and how long they wait. - Which assertions a journey needs. - Whether a journey deserves a Transaction Controller wrapper, unless your reporting reads at transaction level — in which case that becomes a structural call and moves into the table above. Be honest that the line moves. The test for "does this belong in the skeleton?" is whether a reviewer from another team needs it to read the plan. If yes, mandate it. If it only changes how hard the system is pushed, it is not yours. ## How to make it stick A convention nobody can check is a preference. Three mechanisms, in increasing cost: 1. **A template `.jmx`** with the phases and the plan-level nodes already in place and empty. New plans start from a copy, which costs nothing and gets most of the compliance. 2. **A review checklist** phrased in families: does every sampler sit in a journey group; is there a tearDown group and is the shutdown option set; are there Non-Test Elements left in the tree; is functional mode off. 3. **A mechanical check** over the committed `.jmx`, because the two settings most likely to be wrong — `TestPlan.functional_mode` and `TestPlan.tearDown_on_shutdown` — are plain booleans on one element and are trivially greppable. ## The tradeoff to state out loud A skeleton buys readability and costs flexibility. Over-specify and teams fight it or fork it; under-specify and you have a naming convention, not a standard. The defensible middle is: fix the **phases**, fix **where cross-cutting elements hang**, fix the **result of record**, and ban the two families and one checkbox that should never survive into a committed plan. Everything else is the workload owner's call, and a reviewer who wants to argue about thread counts is arguing in the wrong forum. There is no single right answer here, and an interviewer asking this is listening for whether you can separate the structural decisions from the load decisions at all — and whether you can say how the convention would be enforced rather than merely announced.

  • Which single Test Plan setting would you make a review gate, and why that one?
    `TestPlan.tearDown_on_shutdown`. It defaults to false, so a cancelled run silently skips cleanup and leaves seeded state behind for the next run to trip over. It is one boolean on one element, so a mechanical check over the committed .jmx is cheap and catches the whole class.
  • A team argues the skeleton should also fix thread counts. How do you answer?
    Thread counts are a workload decision owned by whoever owns the service, and they change per environment and per release. The skeleton exists so a reviewer can read the plan; it does not make the load correct. Fixing numbers centrally guarantees they will be wrong somewhere and edited anyway.
  • Why ban Non-Test Elements from a committed plan rather than just ignoring them?
    They are authoring tools — the HTTP(S) Test Script Recorder, HTTP Mirror Server, Property Display — that generate no load and no samples. A committed plan holding one is a plan captured but never tidied, and it invites someone to start a proxy on a shared machine during a run.

saying these in an interview costs you the question

  • Mandating thread counts instead of plan structure
  • Leaving an HTTP(S) Test Script Recorder in a committed plan
  • Putting one-time seeding inside the measured Thread Group
  • Announcing a convention with no way to check it
  • Assuming tearDown always runs, so cleanup needs no gate