perf-skills 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +2 -1
- package/package.json +2 -2
- package/skills/perf/SKILL.md +228 -72
- package/skills/perf/evals/evals.json +149 -0
- package/skills/perf/references/tools/gatling.md +286 -286
- package/skills/perf/references/tools/jmeter.md +251 -251
- package/skills/perf/references/tools/k6.md +269 -269
- package/skills/perf/references/tools/locust.md +133 -133
- package/skills/perf/references/topics/correlation.md +406 -0
- package/skills/perf/references/topics/database-testing.md +8 -8
- package/skills/perf/references/topics/modern-architectures.md +15 -15
- package/skills/perf/references/topics/observability.md +3 -3
- package/skills/perf/references/topics/production-testing.md +13 -13
- package/skills/perf/references/topics/protocol-testing.md +15 -15
- package/skills/perf/references/topics/results-analysis.md +13 -13
- package/skills/perf/references/topics/script-generation.md +9 -9
- package/skills/perf/references/topics/test-data.md +6 -6
- package/skills/perf/references/topics/test-execution.md +5 -5
- package/skills/perf/references/topics/workload-design.md +3 -3
|
@@ -1,251 +1,251 @@
|
|
|
1
|
-
# JMeter Reference
|
|
2
|
-
|
|
3
|
-
> Targets: JMeter 5.6+, Plugins Manager 1.10+
|
|
4
|
-
|
|
5
|
-
Apache JMeter is the most widely used open-source performance testing tool. It supports a broad range of protocols and is extended through a rich plugin ecosystem.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Core Concepts
|
|
10
|
-
|
|
11
|
-
| Concept | Description |
|
|
12
|
-
|---|---|
|
|
13
|
-
| **Test Plan** | Root container
|
|
14
|
-
| **Thread Group** | Defines VU count, ramp-up, and loop count |
|
|
15
|
-
| **Sampler** | Makes a request (HTTP, JDBC, JMS, TCP, etc.) |
|
|
16
|
-
| **Controller** | Logic: Loop, If, While, Throughput |
|
|
17
|
-
| **Config Element** | HTTP Defaults, CSV Data Set, Cache Manager |
|
|
18
|
-
| **Pre/Post Processor** | Run before/after a sampler (BeanShell, JSR223) |
|
|
19
|
-
| **Assertion** | Validates the response (Response Code, Duration, JSON) |
|
|
20
|
-
| **Listener** | Collects and displays results (View Results Tree, Summary) |
|
|
21
|
-
| **Timer** | Adds think time (Constant, Gaussian, Synchronizing) |
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Thread Group Configuration Patterns
|
|
26
|
-
|
|
27
|
-
### Standard load ramp
|
|
28
|
-
```
|
|
29
|
-
Thread Group:
|
|
30
|
-
Number of Threads (users): 100
|
|
31
|
-
Ramp-Up Period (seconds): 120 ← 1 VU every 1.2s, avoids thundering herd
|
|
32
|
-
Loop Count: -1 ← run forever until duration
|
|
33
|
-
Duration: 600 ← 10 minutes
|
|
34
|
-
Startup Delay: 0
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Stepping Thread Group (requires JMeter Plugins)
|
|
38
|
-
Use `jp@gc - Stepping Thread Group` for staged load:
|
|
39
|
-
- Start 10 VUs, hold 60s → add 10 every 30s → max 100 VUs → hold 300s → ramp down
|
|
40
|
-
|
|
41
|
-
### Concurrency Thread Group (preferred for modern tests)
|
|
42
|
-
Use `jp@gc - Concurrency Thread Group` for target-concurrency model:
|
|
43
|
-
- Maintains a target concurrency level dynamically, compensates for slow VUs
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## HTTP Sampler Best Practices
|
|
48
|
-
|
|
49
|
-
- Always use **HTTP Request Defaults** config element for base URL/port/protocol
|
|
50
|
-
- Set **Content-Type** header in an HTTP Header Manager at Thread Group level, not per sampler.
|
|
51
|
-
- Use **KeepAlive** (default on) for realistic connection reuse.
|
|
52
|
-
- Use **Follow Redirects** only when your app requires it; disable otherwise for accuracy.
|
|
53
|
-
- Avoid using **View Results Tree** listener in load tests
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Correlation: Extracting Dynamic Values
|
|
58
|
-
|
|
59
|
-
Correlation is the #1 cause of script failures in session-heavy apps.
|
|
60
|
-
|
|
61
|
-
### Regular Expression Extractor
|
|
62
|
-
```
|
|
63
|
-
Reference Name: csrf_token
|
|
64
|
-
Regular Expression: name="_token" value="(.+?)"
|
|
65
|
-
Template: $1$
|
|
66
|
-
Match No.: 1
|
|
67
|
-
Default Value: NOT_FOUND
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### JSON Extractor (REST APIs)
|
|
71
|
-
```
|
|
72
|
-
Reference Name: access_token
|
|
73
|
-
JSON Path: $.data.token
|
|
74
|
-
Match No.: 1
|
|
75
|
-
Default Value: NOT_FOUND
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Boundary Extractor (fastest, no regex overhead)
|
|
79
|
-
```
|
|
80
|
-
Reference Name: session_id
|
|
81
|
-
Left Boundary: "sessionId":"
|
|
82
|
-
Right Boundary: "
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Using Extracted Values
|
|
86
|
-
Reference with `${variable_name}` in subsequent requests.
|
|
87
|
-
|
|
88
|
-
Always add an assertion on the extracted value:
|
|
89
|
-
```
|
|
90
|
-
Response Assertion → Variable: ${csrf_token} → Pattern: NOT_FOUND → Negate
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## CSV Data Set Config
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
Filename: ${__P(data.dir,./data)}/users.csv
|
|
99
|
-
Variable Names: username,password,account_id
|
|
100
|
-
Delimiter: ,
|
|
101
|
-
Allow Quoted Data: true
|
|
102
|
-
Recycle on EOF: true
|
|
103
|
-
Stop Thread on EOF: false
|
|
104
|
-
Sharing Mode: All Threads ← or "Current Thread Group" if isolated data needed
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Tips:**
|
|
108
|
-
- Use `${__P(data.dir,...)}` property for portable paths across environments.
|
|
109
|
-
- For high VU counts, ensure the CSV has at least as many rows as peak VU count to avoid data collisions.
|
|
110
|
-
- In distributed tests, the CSV file must exist on **each injector node**, not just the controller.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## JSR223 Scripting (Groovy)
|
|
115
|
-
|
|
116
|
-
Always use **JSR223** over BeanShell
|
|
117
|
-
|
|
118
|
-
### Pre-processor: Generate a dynamic timestamp
|
|
119
|
-
```groovy
|
|
120
|
-
import java.time.Instant
|
|
121
|
-
vars.put("timestamp", Instant.now().toEpochMilli().toString())
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Post-processor: Parse JSON response
|
|
125
|
-
```groovy
|
|
126
|
-
import groovy.json.JsonSlurper
|
|
127
|
-
def json = new JsonSlurper().parseText(prev.getResponseDataAsString())
|
|
128
|
-
vars.put("userId", json.data.id.toString())
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Pre-processor: Compute HMAC signature
|
|
132
|
-
```groovy
|
|
133
|
-
import javax.crypto.Mac
|
|
134
|
-
import javax.crypto.spec.SecretKeySpec
|
|
135
|
-
def key = vars.get("api_secret")
|
|
136
|
-
def data = vars.get("request_body")
|
|
137
|
-
def mac = Mac.getInstance("HmacSHA256")
|
|
138
|
-
mac.init(new SecretKeySpec(key.bytes, "HmacSHA256"))
|
|
139
|
-
vars.put("signature", mac.doFinal(data.bytes).encodeHex().toString())
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## Assertions
|
|
145
|
-
|
|
146
|
-
### Response Code Assertion
|
|
147
|
-
```
|
|
148
|
-
Field to Test: Response Code
|
|
149
|
-
Pattern: 200
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### JSON Assertion
|
|
153
|
-
```
|
|
154
|
-
JSON Path: $.status
|
|
155
|
-
Expected Value: success
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Duration Assertion
|
|
159
|
-
```
|
|
160
|
-
Duration to assert: 2000 ← flag any response > 2000ms
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Response Size Assertion
|
|
164
|
-
Use to detect incomplete responses
|
|
165
|
-
|
|
166
|
-
**Important:** Add assertions to the **transaction controller level** where possible, not individual samplers, to get meaningful business-transaction-level validation.
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## Transaction Controllers
|
|
171
|
-
|
|
172
|
-
Wrap related HTTP samplers in Transaction Controllers to measure end-to-end business transaction time:
|
|
173
|
-
|
|
174
|
-
```
|
|
175
|
-
Transaction Controller: Login Flow
|
|
176
|
-
├── HTTP Sampler: GET /login
|
|
177
|
-
├── HTTP Sampler: POST /authenticate
|
|
178
|
-
└── HTTP Sampler: GET /dashboard
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
Set **Generate Parent Sample = true** to log only the aggregate transaction (not individual child requests) in results.
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Timers (Think Time)
|
|
186
|
-
|
|
187
|
-
| Timer | Use Case |
|
|
188
|
-
|---|---|
|
|
189
|
-
| Constant Timer | Simple fixed think time |
|
|
190
|
-
| Uniform Random Timer | Range between min–max |
|
|
191
|
-
| Gaussian Random Timer | Bell-curve distribution
|
|
192
|
-
| Throughput Shaping Timer | Target a specific RPS regardless of VU count |
|
|
193
|
-
|
|
194
|
-
Gaussian formula: `delay = Constant + Gaussian(deviation)`
|
|
195
|
-
Realistic web-app think time: Gaussian with constant=3000ms, deviation=1500ms.
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Running JMeter Non-GUI (Command Line)
|
|
200
|
-
|
|
201
|
-
> For distributed testing architecture and setup, see `../topics/test-execution.md`.
|
|
202
|
-
|
|
203
|
-
Always run load tests in non-GUI mode:
|
|
204
|
-
```bash
|
|
205
|
-
jmeter -n \
|
|
206
|
-
-t test.jmx \
|
|
207
|
-
-l results/results.jtl \
|
|
208
|
-
-e -o results/dashboard \
|
|
209
|
-
-Jenv=staging \
|
|
210
|
-
-Jthreads=100 \
|
|
211
|
-
-Jduration=600
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
| Flag | Purpose |
|
|
215
|
-
|---|---|
|
|
216
|
-
| `-n` | Non-GUI mode |
|
|
217
|
-
| `-t` | Test plan path |
|
|
218
|
-
| `-l` | JTL results file |
|
|
219
|
-
| `-e -o` | Generate HTML dashboard after run |
|
|
220
|
-
| `-J` | Set JMeter property (use `${__P(env,dev)}` in plan) |
|
|
221
|
-
| `-G` | Set global property (available to remote engines) |
|
|
222
|
-
|
|
223
|
-
---
|
|
224
|
-
|
|
225
|
-
## Key Plugins (JMeter Plugins Manager)
|
|
226
|
-
|
|
227
|
-
| Plugin | Purpose |
|
|
228
|
-
|---|---|
|
|
229
|
-
| `Concurrency Thread Group` | Maintain target concurrency |
|
|
230
|
-
| `Stepping Thread Group` | Step-ramp load profile |
|
|
231
|
-
| `Throughput Shaping Timer` | Control RPS exactly |
|
|
232
|
-
| `PerfMon` | Collect server-side CPU/memory via agent |
|
|
233
|
-
| `3 Basic Graphs` | Lightweight real-time charting |
|
|
234
|
-
| `JDBC Connection Configuration` | Database load testing |
|
|
235
|
-
| `WebSocket Sampler` | WS protocol support |
|
|
236
|
-
| `gRPC Sampler` | gRPC protocol support |
|
|
237
|
-
|
|
238
|
-
Install plugins via: **Options → Plugins Manager → Available Plugins**
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
## JMeter-Specific Tips
|
|
243
|
-
|
|
244
|
-
- **Always run in non-GUI mode** for load tests
|
|
245
|
-
- **Use HTTP Request Defaults**
|
|
246
|
-
- **Never put listeners inside loops**
|
|
247
|
-
- **Use JSR223 (Groovy) over BeanShell**
|
|
248
|
-
- **Set JVM heap** for large tests: `JVM_ARGS="-Xms2g -Xmx4g" jmeter -n -t test.jmx`
|
|
249
|
-
|
|
250
|
-
> For CI/CD integration (Maven, GitHub Actions, GitLab, Jenkins), see `../topics/test-execution.md`.
|
|
251
|
-
> For anti-patterns, assertions, think time, and parameterization principles, see **Key Principles** in `SKILL.md`.
|
|
1
|
+
# JMeter Reference
|
|
2
|
+
|
|
3
|
+
> Targets: JMeter 5.6+, Plugins Manager 1.10+
|
|
4
|
+
|
|
5
|
+
Apache JMeter is the most widely used open-source performance testing tool. It supports a broad range of protocols and is extended through a rich plugin ecosystem.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Concepts
|
|
10
|
+
|
|
11
|
+
| Concept | Description |
|
|
12
|
+
|---|---|
|
|
13
|
+
| **Test Plan** | Root container - the `.jmx` file |
|
|
14
|
+
| **Thread Group** | Defines VU count, ramp-up, and loop count |
|
|
15
|
+
| **Sampler** | Makes a request (HTTP, JDBC, JMS, TCP, etc.) |
|
|
16
|
+
| **Controller** | Logic: Loop, If, While, Throughput |
|
|
17
|
+
| **Config Element** | HTTP Defaults, CSV Data Set, Cache Manager |
|
|
18
|
+
| **Pre/Post Processor** | Run before/after a sampler (BeanShell, JSR223) |
|
|
19
|
+
| **Assertion** | Validates the response (Response Code, Duration, JSON) |
|
|
20
|
+
| **Listener** | Collects and displays results (View Results Tree, Summary) |
|
|
21
|
+
| **Timer** | Adds think time (Constant, Gaussian, Synchronizing) |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Thread Group Configuration Patterns
|
|
26
|
+
|
|
27
|
+
### Standard load ramp
|
|
28
|
+
```
|
|
29
|
+
Thread Group:
|
|
30
|
+
Number of Threads (users): 100
|
|
31
|
+
Ramp-Up Period (seconds): 120 ← 1 VU every 1.2s, avoids thundering herd
|
|
32
|
+
Loop Count: -1 ← run forever until duration
|
|
33
|
+
Duration: 600 ← 10 minutes
|
|
34
|
+
Startup Delay: 0
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Stepping Thread Group (requires JMeter Plugins)
|
|
38
|
+
Use `jp@gc - Stepping Thread Group` for staged load:
|
|
39
|
+
- Start 10 VUs, hold 60s → add 10 every 30s → max 100 VUs → hold 300s → ramp down
|
|
40
|
+
|
|
41
|
+
### Concurrency Thread Group (preferred for modern tests)
|
|
42
|
+
Use `jp@gc - Concurrency Thread Group` for target-concurrency model:
|
|
43
|
+
- Maintains a target concurrency level dynamically, compensates for slow VUs
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## HTTP Sampler Best Practices
|
|
48
|
+
|
|
49
|
+
- Always use **HTTP Request Defaults** config element for base URL/port/protocol - never hardcode in individual samplers.
|
|
50
|
+
- Set **Content-Type** header in an HTTP Header Manager at Thread Group level, not per sampler.
|
|
51
|
+
- Use **KeepAlive** (default on) for realistic connection reuse.
|
|
52
|
+
- Use **Follow Redirects** only when your app requires it; disable otherwise for accuracy.
|
|
53
|
+
- Avoid using **View Results Tree** listener in load tests - it's memory-intensive; use it only during script development.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Correlation: Extracting Dynamic Values
|
|
58
|
+
|
|
59
|
+
Correlation is the #1 cause of script failures in session-heavy apps.
|
|
60
|
+
|
|
61
|
+
### Regular Expression Extractor
|
|
62
|
+
```
|
|
63
|
+
Reference Name: csrf_token
|
|
64
|
+
Regular Expression: name="_token" value="(.+?)"
|
|
65
|
+
Template: $1$
|
|
66
|
+
Match No.: 1
|
|
67
|
+
Default Value: NOT_FOUND
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### JSON Extractor (REST APIs)
|
|
71
|
+
```
|
|
72
|
+
Reference Name: access_token
|
|
73
|
+
JSON Path: $.data.token
|
|
74
|
+
Match No.: 1
|
|
75
|
+
Default Value: NOT_FOUND
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Boundary Extractor (fastest, no regex overhead)
|
|
79
|
+
```
|
|
80
|
+
Reference Name: session_id
|
|
81
|
+
Left Boundary: "sessionId":"
|
|
82
|
+
Right Boundary: "
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Using Extracted Values
|
|
86
|
+
Reference with `${variable_name}` in subsequent requests.
|
|
87
|
+
|
|
88
|
+
Always add an assertion on the extracted value:
|
|
89
|
+
```
|
|
90
|
+
Response Assertion → Variable: ${csrf_token} → Pattern: NOT_FOUND → Negate
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## CSV Data Set Config
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Filename: ${__P(data.dir,./data)}/users.csv
|
|
99
|
+
Variable Names: username,password,account_id
|
|
100
|
+
Delimiter: ,
|
|
101
|
+
Allow Quoted Data: true
|
|
102
|
+
Recycle on EOF: true
|
|
103
|
+
Stop Thread on EOF: false
|
|
104
|
+
Sharing Mode: All Threads ← or "Current Thread Group" if isolated data needed
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Tips:**
|
|
108
|
+
- Use `${__P(data.dir,...)}` property for portable paths across environments.
|
|
109
|
+
- For high VU counts, ensure the CSV has at least as many rows as peak VU count to avoid data collisions.
|
|
110
|
+
- In distributed tests, the CSV file must exist on **each injector node**, not just the controller.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## JSR223 Scripting (Groovy)
|
|
115
|
+
|
|
116
|
+
Always use **JSR223** over BeanShell - Groovy is compiled and cached, BeanShell is not.
|
|
117
|
+
|
|
118
|
+
### Pre-processor: Generate a dynamic timestamp
|
|
119
|
+
```groovy
|
|
120
|
+
import java.time.Instant
|
|
121
|
+
vars.put("timestamp", Instant.now().toEpochMilli().toString())
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Post-processor: Parse JSON response
|
|
125
|
+
```groovy
|
|
126
|
+
import groovy.json.JsonSlurper
|
|
127
|
+
def json = new JsonSlurper().parseText(prev.getResponseDataAsString())
|
|
128
|
+
vars.put("userId", json.data.id.toString())
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Pre-processor: Compute HMAC signature
|
|
132
|
+
```groovy
|
|
133
|
+
import javax.crypto.Mac
|
|
134
|
+
import javax.crypto.spec.SecretKeySpec
|
|
135
|
+
def key = vars.get("api_secret")
|
|
136
|
+
def data = vars.get("request_body")
|
|
137
|
+
def mac = Mac.getInstance("HmacSHA256")
|
|
138
|
+
mac.init(new SecretKeySpec(key.bytes, "HmacSHA256"))
|
|
139
|
+
vars.put("signature", mac.doFinal(data.bytes).encodeHex().toString())
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Assertions
|
|
145
|
+
|
|
146
|
+
### Response Code Assertion
|
|
147
|
+
```
|
|
148
|
+
Field to Test: Response Code
|
|
149
|
+
Pattern: 200
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### JSON Assertion
|
|
153
|
+
```
|
|
154
|
+
JSON Path: $.status
|
|
155
|
+
Expected Value: success
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Duration Assertion
|
|
159
|
+
```
|
|
160
|
+
Duration to assert: 2000 ← flag any response > 2000ms
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Response Size Assertion
|
|
164
|
+
Use to detect incomplete responses - flag if body < 100 bytes unexpectedly.
|
|
165
|
+
|
|
166
|
+
**Important:** Add assertions to the **transaction controller level** where possible, not individual samplers, to get meaningful business-transaction-level validation.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Transaction Controllers
|
|
171
|
+
|
|
172
|
+
Wrap related HTTP samplers in Transaction Controllers to measure end-to-end business transaction time:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
Transaction Controller: Login Flow
|
|
176
|
+
├── HTTP Sampler: GET /login
|
|
177
|
+
├── HTTP Sampler: POST /authenticate
|
|
178
|
+
└── HTTP Sampler: GET /dashboard
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Set **Generate Parent Sample = true** to log only the aggregate transaction (not individual child requests) in results.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Timers (Think Time)
|
|
186
|
+
|
|
187
|
+
| Timer | Use Case |
|
|
188
|
+
|---|---|
|
|
189
|
+
| Constant Timer | Simple fixed think time |
|
|
190
|
+
| Uniform Random Timer | Range between min–max |
|
|
191
|
+
| Gaussian Random Timer | Bell-curve distribution - most realistic |
|
|
192
|
+
| Throughput Shaping Timer | Target a specific RPS regardless of VU count |
|
|
193
|
+
|
|
194
|
+
Gaussian formula: `delay = Constant + Gaussian(deviation)`
|
|
195
|
+
Realistic web-app think time: Gaussian with constant=3000ms, deviation=1500ms.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Running JMeter Non-GUI (Command Line)
|
|
200
|
+
|
|
201
|
+
> For distributed testing architecture and setup, see `../topics/test-execution.md`.
|
|
202
|
+
|
|
203
|
+
Always run load tests in non-GUI mode:
|
|
204
|
+
```bash
|
|
205
|
+
jmeter -n \
|
|
206
|
+
-t test.jmx \
|
|
207
|
+
-l results/results.jtl \
|
|
208
|
+
-e -o results/dashboard \
|
|
209
|
+
-Jenv=staging \
|
|
210
|
+
-Jthreads=100 \
|
|
211
|
+
-Jduration=600
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
| Flag | Purpose |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `-n` | Non-GUI mode |
|
|
217
|
+
| `-t` | Test plan path |
|
|
218
|
+
| `-l` | JTL results file |
|
|
219
|
+
| `-e -o` | Generate HTML dashboard after run |
|
|
220
|
+
| `-J` | Set JMeter property (use `${__P(env,dev)}` in plan) |
|
|
221
|
+
| `-G` | Set global property (available to remote engines) |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Key Plugins (JMeter Plugins Manager)
|
|
226
|
+
|
|
227
|
+
| Plugin | Purpose |
|
|
228
|
+
|---|---|
|
|
229
|
+
| `Concurrency Thread Group` | Maintain target concurrency |
|
|
230
|
+
| `Stepping Thread Group` | Step-ramp load profile |
|
|
231
|
+
| `Throughput Shaping Timer` | Control RPS exactly |
|
|
232
|
+
| `PerfMon` | Collect server-side CPU/memory via agent |
|
|
233
|
+
| `3 Basic Graphs` | Lightweight real-time charting |
|
|
234
|
+
| `JDBC Connection Configuration` | Database load testing |
|
|
235
|
+
| `WebSocket Sampler` | WS protocol support |
|
|
236
|
+
| `gRPC Sampler` | gRPC protocol support |
|
|
237
|
+
|
|
238
|
+
Install plugins via: **Options → Plugins Manager → Available Plugins**
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## JMeter-Specific Tips
|
|
243
|
+
|
|
244
|
+
- **Always run in non-GUI mode** for load tests - GUI mode consumes JMeter's own resources and distorts results.
|
|
245
|
+
- **Use HTTP Request Defaults** - hardcoded hosts make environment switching painful.
|
|
246
|
+
- **Never put listeners inside loops** - View Results Tree in a loop will OOM the JVM.
|
|
247
|
+
- **Use JSR223 (Groovy) over BeanShell** - Groovy is compiled and cached; BeanShell is interpreted per invocation.
|
|
248
|
+
- **Set JVM heap** for large tests: `JVM_ARGS="-Xms2g -Xmx4g" jmeter -n -t test.jmx`
|
|
249
|
+
|
|
250
|
+
> For CI/CD integration (Maven, GitHub Actions, GitLab, Jenkins), see `../topics/test-execution.md`.
|
|
251
|
+
> For anti-patterns, assertions, think time, and parameterization principles, see **Key Principles** in `SKILL.md`.
|