Next Practical Step
Open a small plan in GUI, use Copy Code on an HTTP sampler, and compile that fragment against JMeter 5.6+ libraries.
Build JMeter plans as code with the 5.6 Java and Kotlin DSL: ListedHashTree, Copy Code from GUI, CI-friendly workflows, and code-first vs k6 trade-offs.
Teams leaving GUI-centric workflows for tools like k6 often still need JMeter’s protocol breadth or existing JVM skills. JMeter 5.6 introduced experimental APIs and Kotlin/Java DSL helpers to build plans programmatically. This guide summarizes the official Building a Test Plan Programmatically chapter and how to combine it with CLI execution, git, and CI.
| Driver | How programmatic plans help |
|---|---|
| PR review | Diff Java/Kotlin instead of huge XML |
| Reuse | Share builders for headers, auth, HTTP defaults |
| Generate many variants | Loops in code create samplers/data |
| Hybrid teams | GUI for discovery, code for steady-state suites |
You can still save/run .jmx; code is another authoring front-end to the same engine.
Official model:
ListedHashTree.ListedHashTree, not plain HashTree, because HashTree does not honour element order and children may shuffle unexpectedly.From the manual’s Debug Sampler example pattern:
ListedHashTree root = new ListedHashTree();TestPlan testPlan = new TestPlan();ListedHashTree testPlanSubtree = root.add(testPlan);ThreadGroup threadGroup = new ThreadGroup();threadGroup.setName("Search Order Thread Group");ListedHashTree threadGroupSubtree = testPlanSubtree.add(threadGroup);DebugSampler debugSampler = new DebugSampler();threadGroupSubtree.add(debugSampler);TestPlan, keep returned subtree.ThreadGroup under plan.(Your imports and exact setters match the JMeter version JARs on the classpath.)
The manual documents a Copy Code context action on plan elements. It generates code for the element and its children (example shows Kotlin DSL output for an HTTP sampler). Workflow:
This is the fastest bridge for GUI users moving toward code.
The programmatic chapter covers creating a plan with Kotlin DSL (testTree builder style, class references such as TestPlan::class, unary plus for childless elements). Extension functions on TreeBuilder factor common patterns (e.g. a threadGroup helper with default threads/ramp-up).
See the manual sections:
for syntax details and screenshots of generated code.
Similarly, a Java DSL uses testTree with builder lambdas: b.add(Class, consumer) to configure properties and nest children. Prefer this when the team standardizes on Java without Kotlin.
| Concern | k6 | JMeter programmatic |
|---|---|---|
| Language | JS/TS | Java/Kotlin (+ jmx) |
| Engine | Go binary | JVM JMeter engine |
| Protocols | HTTP-centric strengths | Broad JMeter sampler set |
| Maturity of DSL | Central product focus | Experimental helpers in 5.6 |
| Execution | k6 run | Still jmeter -n or embedded engine |
You do not have to abandon JMeter to get reviewable code; you may adopt DSL authoring while keeping CLI reports and distributed mode.
Deep dive comparisons: JMeter vs alternatives.
threads, host) for CLI parity.If you only need versioned XML, committing cleaned .jmx with \${__P} is still valid code-adjacent practice.
Programmatic authoring requires JMeter libraries on the module classpath (ApacheJMeter_core, protocol modules you use, etc.). Match versions to the JMeter you run for load. Plugin classes used in code must exist on workers too (plugins).
| Mode | Notes |
|---|---|
| Generate jmx, run CLI | Familiar ops path -n -t -l -e -o |
| Embedded engine in JVM | Advanced; ensure shutdown and result collection |
| Distributed | Same remote testing rules; plan serialization must include all classes |
Unit-test that the tree contains expected labels/counts. Smoke-run with 1 thread before performance environments. Experimental APIs deserve characterization tests when you upgrade JMeter.
HashTree instead of ListedHashTree → order bugs.__P patterns for runtime.JMeter 5.6 documents it as experimental. Many teams use it successfully but should pin versions and watch release notes.
Yes. Programmatic APIs are optional. Versioned jmx plus CLI remains fully supported.
Choose based on team language. Both are documented. Copy Code often emits Kotlin DSL examples in the manual screenshots.
No. Real load still should run non-GUI with minimal listeners regardless of how the plan was authored.
Rebuild scenarios with HTTP samplers or Copy Code from a recorded flow; map checks to assertions; run CLI reports. Protocol-only k6 scripts map cleanly; browser-level k6 features do not.
In the JMeter GUI context menu on a tree element (documented with screenshot in the programmatic chapter).