Starter Script Template
Rather than starting a new project from an empty Test Plan, start from this one. It has the whole checklist from Script Requirements already wired in.
๐ฅ Download loadlitmus-starter.jmx โ source: static/templates/loadlitmus-starter.jmx in this repository.
What is in itโ
Warning: Test Editor is in beta and has known bugs. Use it to look at a script, not as the place you build one. Keep a copy of the
.jmxbefore saving from the editor, and check changes in JMeter's own GUI.

Test Plan โ comment: what this test answers, and what it does NOT
โโโ UDV "Environment" host ยท port ยท protocol ยท password ยท smoke ยท thinkMin ยท thinkMax
โโโ HTTP Request Defaults ยท Global Headers ยท Cookie Manager ยท Cache Manager
โโโ Thread Group "01 - <PERSONA A>" users/ramp/loops = ${__P(a.users)} etc.
โโโ CSV - users ${__P(user.dir)}/${__P(a.csv,test_data/users.csv)}
โโโ TC01_Login
โ โโโ 01_GET_Login Init all vars = NOT_FOUND ยท extract csrf ยท assert 200
โ โโโ 02_POST_Login think time ยท extract landing_url ยท assert not bounced ยท save failed response
โโโ If: logged in ${__jexl3("${landing_url}" != "NOT_FOUND")}
โ โโโ TC02_<READ_ONLY_JOURNEY> 03_GET_<PAGE> ยท assert 200 ยท assert content ยท save failed response
โโโ If: smoke == false
โโโ TC03_<SUBMIT> 04_POST_<SUBMIT> ยท assert saved ยท save failed response
| Feature | Why it is there |
|---|---|
${__P(...)} directly in the Thread Group | Keeps the Load card editable |
| UDV control panel with a description per row | One place to change settings; explains itself to the next person |
password with no default | Typed into the parameter form, never stored in the file |
${__P(user.dir)}/... CSV path | Same path works on the master and on every slave |
NOT_FOUND init + If guards | A failed login stops that user instead of flooding the error rate |
smoke flag around the write steps | Smoke runs leave the system untouched |
| Result Savers, failures only | Fleet can collect the actual failing pages |
| Content assertions, not just HTTP 200 | A 200 carrying an error page is still a 200 |
| No listeners, no Backend Listener | LoadLitmus writes the JTL and injects monitoring itself |
Fill inโ
| Placeholder | Where |
|---|---|
<CLIENT> <SYSTEM> - <the one question...> | Test Plan name and its comment |
host, protocol, port defaults | UDV "Environment" |
/login, /home, /submit | Sampler paths |
name="_token" value="([^"]+)" | The csrf extractor's regex |
<SOMETHING ONLY THIS PAGE CONTAINS> | Content assertions |
USERNAME | CSV column names |
01 - <PERSONA A>, TC02_<READ_ONLY_JOURNEY> | Thread group and transaction names |
Adding a second personaโ
Copy the whole Thread Group, rename it 02 - <PERSONA B>, and rename its parameters a.users โ b.users, a.ramp โ b.ramp, a.loops โ b.loops, a.csv โ b.csv. The Runner then shows one load row per persona.
Keep every group a classic Thread Group. A setUp or tearDown group switches the Load card off, and you go back to setting load from the parameter form.
Running itโ
- Copy the file into
data/projects/<slug>/test_plan/and rename it. - Put the CSV in
test_data/with aUSERNAMEheader. - On the Runner page, select it and check that the Load card shows one row per persona and Test Data lists the CSV.
- Smoke run: 1 user, 1 iteration,
smoke=true. - Real run: raise the load, set
smoke=falsewhen the write steps should fire.
What was verifiedโ
Run against a local stub server with JMeter 5.6.3 on 2026-09-23, and through LoadLitmus 1.4.5:
| Check | Result |
|---|---|
2 users, smoke=false | All 4 samplers and 3 transactions pass |
smoke=true (default) | The submit step is skipped |
| Broken login | The guard stops the user after 02_POST_Login; the failing page lands in failed_response/02_login/alice.unknown |
| LoadLitmus Load card | Editable; a 50 VU / 60 s ramp / 5 iteration override was applied to the run |
| Secret scan | No tokens, hosts or absolute paths in the file |
Habits worth keepingโ
The template is the distillation of several scripts from finished projects. Habits worth naming:
- A Test Plan comment stating the one question the test answers, a description on every variable, and a setUp "preflight" check that catches a wrong environment before any load starts.
- One OAuth token fetched once and shared through
props.put(), so thousands of users do not each log in. - Retry loops around an unreliable SSO, and a Synchronizing Timer to release users together.
NOT_FOUNDguards, and failed responses saved per user and per step.${persona}in every sampler name, so the report splits by role.