Checkpoint Lab — Test Plan Tree, Scope, Execution Order, and Component Semantics
Complete the chapter by proving tree semantics rather than memorizing them. Build a two-request loopback plan, predict scope and execution order, capture variables in one bounded Debug Sampler run, deliberately mis-scope the header, diagnose Beta's planned assertion failure, restore the tree, and retain before/broken/after evidence.
Learning objectives
- Construct and annotate a multi-request tree with explicit scope.
- Predict sampler order and applicable component phases before running.
- Use Debug Sampler/View Results Tree only for a bounded variable-inspection pass.
-
Run lean CLI copies with unique JTL and
jmeter.log. - Introduce one reversible Header Manager mis-scope and diagnose resulting assertion evidence.
- Restore the tree and state what the experiment proves and does not prove.
1. Scenario, assumptions, and ceiling
| Item | Checkpoint baseline |
|---|---|
| JMeter | Apache JMeter 5.6.3. |
| Java | Java 17 JDK lab baseline; 5.6.3 itself requires Java 8+. |
| Plugins | None. |
| Target | http://127.0.0.1:8000 only. |
| Threads / loops | 1 thread × 1 loop. |
| Network samplers | Alpha then Beta; exactly 2 target requests per run. |
| Broad elements | Header Manager, 150 ms Timer, Response Assertion, Regular Expression Extractor under Scope Lab. |
| Diagnostics | Debug Sampler + View Results Tree only in debug copy. |
| Load evidence | CLI copy with diagnostics disabled. |
2. Create a clean checkpoint workspace
jmeter-ch03-checkpoint/
├── fixtures/scope_fixture.py
├── plans/
│ ├── 01-broad-debug.jmx
│ ├── 01-broad-load.jmx
│ ├── 02-header-broken-debug.jmx
│ ├── 02-header-broken-load.jmx
│ ├── 03-restored-debug.jmx
│ └── 03-restored-load.jmx
├── evidence/
│ ├── scope-map.txt
│ ├── predictions.txt
│ └── tree-diff.txt
└── results/
Save the Lesson 2 fixture as
fixtures/scope_fixture.py and start it separately.
3. Build and save the intended broad tree
Test Plan
└── Thread Group — 1 thread, 1 loop
├── HTTP Request Defaults — http / 127.0.0.1 / 8000
├── Simple Controller — Scope Lab
│ ├── HTTP Header Manager — X-Lab-Scope: broad
│ ├── Constant Timer — 150 ms
│ ├── Response Assertion — body contains "scope_header": "broad"
│ ├── Regular Expression Extractor
│ │ └── last_request_id <- "request_id":\s*(\d+)
│ ├── HTTP Request — Alpha — GET /alpha
│ └── HTTP Request — Beta — GET /beta
├── Debug Sampler — Inspect variables after Scope Lab
└── View Results Tree — AUTHORING DEBUG ONLY
Save 01-broad-debug.jmx. Duplicate it as
01-broad-load.jmx and disable Debug Sampler/View
Results Tree in the load copy.
4. Write the scope map before execution
| Sampler | Header | Timer | Post-Processor | Assertion | Observation |
|---|---|---|---|---|---|
| Alpha | broad | 150 ms before | extract Alpha request_id | expects broad | Debug/JTL. |
| Beta | broad | 150 ms before | extract Beta request_id | expects broad | Debug/JTL. |
| Debug Sampler | outside Scope Lab | outside | outside | outside | Reads thread variables only. |
Expected applicable sequence for Alpha/Beta is configuration → timer → HTTP sampler → extractor → assertion → listener. There is no Pre-Processor in this checkpoint.
5. Write predictions before baseline
- Target receives Alpha then Beta: two requests total.
- Both responses echo
scope_header=broad. - Both assertions pass.
-
Broad extractor runs after each; after Beta,
last_request_idequals Beta's ID. - Broad timer delays both request starts; sampler elapsed remains dominated by fixture response time.
6. Bounded Debug Sampler verification
Start a fresh fixture and run 01-broad-debug.jmx once
in GUI. Confirm Alpha/Beta response bodies, both green assertions,
Debug Sampler last_request_id, and capture a tree
screenshot/text export. Restart the fixture before CLI evidence.
7. Baseline CLI evidence run
mkdir -p results/01-broad
jmeter -n -t plans/01-broad-load.jmx \
-l results/01-broad/results.jtl \
-j results/01-broad/jmeter.log
New-Item -ItemType Directory -Force results\01-broad | Out-Null
jmeter.bat -n `
-t plans\01-broad-load.jmx `
-l results\01-broad\results.jtl `
-j results\01-broad\jmeter.log
Verify fixture total 2 (Alpha 1, Beta 1), two network JTL rows, and zero failed samples.
8. Deliberately mis-scope one element
Copy broad debug plan to 02-header-broken-debug.jmx.
Move only Header Manager under Alpha; leave Response Assertion
broad.
- Alpha still passes with broad header.
- Beta reaches target without X-Lab-Scope.
-
Beta response is valid JSON with
scope_header=<missing>. - Beta fails only because broad assertion still requires broad.
- Broad extractor still runs after Beta, so Debug Sampler still shows Beta request ID.
9. Verify broken tree without hiding the failure
Restart fixture and run broken debug plan once. Preserve tree image/text, Alpha/Beta bodies, Beta assertion failure, Debug variable, and fixture stats. This is a planned scope/correctness failure, not target availability failure.
10. Run broken state through CLI
Create the load copy by disabling Debug Sampler/View Results Tree, restart fixture, and run:
mkdir -p results/02-header-broken
jmeter -n -t plans/02-header-broken-load.jmx \
-l results/02-header-broken/results.jtl \
-j results/02-header-broken/jmeter.log
Expected: Alpha succeeds, Beta is failed by assertion, fixture still reports two requests. Preserve the failed JTL.
11. Diagnose by tree semantics
| Evidence | Observation | Conclusion |
|---|---|---|
| Fixture stats | Alpha 1, Beta 1 | Network execution order/count unchanged. |
| Alpha response | scope_header=broad | Narrow Header Manager applies to Alpha. |
| Beta response | scope_header=<missing> | Header Manager no longer applies to Beta. |
| Beta assertion | Failed | Broad assertion still applies. |
| Debug variable | Beta request ID | Extractor remains broad. |
| jmeter.log | No engine-startup problem expected | Fault is tree correctness, not toolchain startup. |
Given original intent that both requests require the header, the smallest correction is restoring Header Manager to Scope Lab.
12. Restore, rerun, compare
Copy broken plan to 03-restored-debug.jmx, move Header
Manager back under Scope Lab, create load copy with diagnostics
disabled, restart fixture, and run into
results/03-restored. Expect two requests and two
successful samples.
13. Timing evidence and validity
Use the Lesson 2 JTL analyzer on baseline/broken/restored files. The header move should change correctness, not configured timer or synthetic service delay. Do not claim a performance regression from tiny-run timing noise.
import csv
from pathlib import Path
path=Path('results/run-001/results.jtl')
rows=list(csv.DictReader(path.open(encoding='utf-8')))
print(f'samples={len(rows)}')
for r in rows:
print(f"{r['label']}: success={r['success']} elapsed_ms={r['elapsed']} timestamp={r['timeStamp']}")
network=[r for r in rows if r['label'] in {'Alpha','Beta'}]
if len(network)==2:
print('alpha_to_beta_start_gap_ms='+str(int(network[1]['timeStamp'])-int(network[0]['timeStamp'])))
14. Required evidence packet
| Artifact | Why it matters |
|---|---|
| Broad/broken/restored JMX | Exact tree states. |
| Tree screenshots/text exports | Human-reviewable scope placement. |
| Scope map + predictions | Expectations existed before execution. |
| Bounded Debug Sampler variables | Extractor/thread-variable lifecycle. |
| Three CLI JTLs | Baseline, deliberate failure, restored raw evidence. |
| Three jmeter.log files | Engine/runtime provenance. |
| Fixture stats | Independent target request-count evidence. |
| Tree diff | Shows one intended parent-scope change. |
| Validity note | Prevents unsupported capacity claims. |
15. Write the validity note
16. Cleanup and rollback
- Stop the Python fixture.
- Keep before/broken/restored JMX and result evidence through review.
- Disable/remove authoring-only Debug Sampler/View Results Tree from the load profile that continues to Chapter 04.
- No production systems, credentials, certificates, databases, remote engines, containers, plugins, or system-wide settings were changed.
17. What Chapter 03 adds to the operating model
Chapter 01 defined experiment intent; Chapter 02 added toolchain provenance; Chapter 03 adds execution-architecture provenance. A reviewer can now trace each sampler through its ancestors and explain configuration, waits, extraction, assertions, and result observers.
Chapter 04 builds on this to design virtual users, ramp-up, loops, duration, and workload shape deliberately.
Knowledge check
In the broken checkpoint, why does Beta still reach the fixture?
Moving Header Manager changes request configuration, not controller/sampler execution order; Beta remains a sampler under Scope Lab.
Why is Beta failed even though server returns HTTP 200?
The broad Response Assertion evaluates Beta response and does not find broad header value, so it changes SampleResult success state.
What proves the extractor remained broad?
Debug Sampler after Scope Lab still shows Beta request ID because Beta continues to trigger the controller-scoped extractor.
Why retain the broken JTL after restored run passes?
It is first-failure evidence supporting the diagnosis and proving the correction rather than merely showing a final green state.
What is the bridge to Chapter 04?
With scope/execution understood, Thread Group users, ramp-up, loops, duration, and workload models can change without confusing scheduling with component scope.
Official references and version notes
- Elements of a Test Plan — execution order, scoping rules, variables/properties, timers, assertions, configuration elements, processors, listeners, controllers, and samplers.
- Component Reference — Header Manager, Constant Timer, Response Assertion, Regular Expression Extractor, Debug Sampler, Transaction Controller, and listeners.
- Functions and Variables — sampler-context functions and variable semantics.
- Hints and Tips — current quick-add bindings for common debug elements.
- Getting Started and Best Practices — GUI authoring versus CLI load execution and lean result collection.
- Apache JMeter downloads — current production release and Java requirement.
Version-sensitive statements were rechecked against current Apache
JMeter primary documentation on 2026-09-04. The baseline is Apache
JMeter 5.6.3 with a Java 17 JDK for labs and no
third-party plugins; JMeter 5.6.3 itself requires Java 8+. The
current Test Plan manual defines applicable execution order as
Configuration Elements → Pre-Processors → Timers → Sampler →
Post-Processors → Assertions → Listeners. Controllers and samplers
are primarily ordered; listeners, configuration elements,
pre/post-processors, assertions, and timers are
hierarchical/scoped. Mandatory traffic is restricted to
http://127.0.0.1:8000, one thread and one loop. Debug
Sampler/View Results Tree are bounded GUI diagnostics only; CLI
remains the load-evidence path.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.