A JMeter test without assertions is a traffic generator, not a test. Without assertions, every response — including 500 errors, empty bodies, and timeouts — appears as a green success in your results. Assertions are the layer that turns raw sampler output into a meaningful pass or fail signal.
What assertions do
Assertions evaluate a sampler's response after it arrives. If an assertion fails, JMeter marks the entire sample as failed — it turns red in listeners, increments the error counter, and contributes to the error rate in your reports. One failed assertion on one sample marks that sample as failed; the other samples in the same iteration are unaffected.
Unlike K6 checks (which simply record a pass/fail without affecting the sample's success status), JMeter assertions directly change the sample's outcome. A JMeter assertion failure is an error — it counts toward the error rate, appears in results.jtl, and can trigger CI/CD build failures if you have threshold checks on error rate.
Add assertions by right-clicking a sampler → Add → Assertions. Multiple assertions on the same sampler all run; the sample fails if any one of them fails.
Response Assertion
The most versatile assertion in JMeter. It checks a field of the response against one or more patterns.
Field to test:
- Response Code: the HTTP status code (
200,404,500) - Response Message: the HTTP status text (
OK,Not Found) - Response Headers: all headers as a single string
- Text Response: the full response body as text
- Request Headers: what JMeter sent (useful for debugging)
- URL Sampled: the final URL after redirects
- Document: the response parsed as a document (slow — avoid in load tests)
Pattern Matching Rules:
| Rule | Behaviour |
|---|---|
| Contains | Pattern appears anywhere in the field (regex) |
| Matches | Entire field matches the pattern (regex, anchored) |
| Equals | Exact string match, no regex |
| Substring | Exact string appears anywhere (no regex) |
| Not | Inverts the result |
| Or | Any pattern matching is sufficient (instead of all) |
Example: verify HTTP 200
- Field: Response Code
- Rule: Equals
- Pattern:
200
Example: verify any 2xx response
- Field: Response Code
- Rule: Matches
- Pattern:
2\d{2}
Example: verify response body contains a field
- Field: Text Response
- Rule: Substring
- Pattern:
"status":"active"
Example: verify response does NOT contain an error message
- Field: Text Response
- Rule: Substring + Not checked
- Pattern:
Internal Server Error
Duration Assertion
Asserts that the sampler completed within a time limit.
Configuration: Duration in milliseconds = 2000
Any sampler that takes longer than 2000ms to receive a complete response is marked as failed. The response itself may be perfectly valid — the assertion fails purely on timing.
Use Duration Assertion to enforce per-request SLAs directly in the test plan. For example, a login request must complete in under 1000ms and a search request in under 3000ms — add separate Duration Assertions to each sampler with the relevant threshold.
Duration Assertion is an alternative approach to K6's thresholds. In K6 you define http_req_duration: ['p(95)<500'] at test level. In JMeter, Duration Assertion fires per-request — if the 96th percentile request fails the assertion, that specific request appears as a failure in the results.
- – Status code (200, 4xx, 5xx)
- – Body content — substring or regex
- – Response headers
- – URL after redirects
- – Response time threshold in ms
- – Per-request SLA enforcement
- – Any request over limit = fail
- – Total bytes / KB / MB
- – Greater than / Less than / Equals
- – Detects empty or truncated responses
- JSON Assertion — JSONPath –
- XPath Assertion — XML/HTML –
- HTML Assertion — W3C validity –
Size Assertion
Asserts on the number of bytes in the response. Configuration fields:
- Size to assert on: Total response / Body / Response headers
- Type of comparison:
=,!=,>,<,>=,<= - Size in bytes:
100
Useful patterns:
> 0— catch empty responses (the server responded but sent no body)< 10485760— catch unexpectedly large responses (10MB limit)= 0— verify a 204 No Content response has no body
Size Assertion is particularly valuable for file download tests and for catching truncated responses that would pass a status code check but contain incomplete data.
HTML Assertion
Validates the response body as HTML against the W3C Tidy library. Marks the sample as failed if the HTML contains parse errors.
Useful for: verifying that API responses returning HTML fragments (CMS content, email templates) are well-formed. Not useful for pure JSON APIs. Adds significant processing overhead — do not use in load tests.
Applying assertions effectively
A practical approach for most JMeter test plans:
- Always assert status code — add a Response Assertion checking for
2\d{2}on every sampler. This catches 4xx and 5xx errors that JMeter would otherwise count as successes. - Assert critical business fields with JSON Assertion — for key endpoints (login, checkout), verify the response body contains the expected structure.
- Add Duration Assertion to SLA-critical requests — login < 1s, search < 3s, payment < 5s.
- Skip Size and HTML assertions in load tests — they add CPU overhead per sample. Reserve them for functional verification runs with a single user.
⚠️ Common mistakes
- No assertions — relying on visual inspection. Running a 10,000-request load test and checking for red rows in View Results Tree is not a testing strategy. Add assertions so JMeter's error rate metric is meaningful. A test with 0% errors but no assertions is a lie — you simply have not told JMeter what counts as wrong.
- Using Equals instead of Matches for flexible status codes.
Equals 200fails on a valid201 Createdresponse. UseMatches 2\d{2}for a range, or add multiple patterns with Or mode to accept both 200 and 201. - Adding Duration Assertion at Thread Group level instead of per sampler. A Duration Assertion at Thread Group level applies to every sampler in the group — including fast internal calls. An authentication call taking 200ms might have a reasonable 1000ms limit, but a static asset request taking 50ms would fail a 100ms assertion meant for the API. Apply Duration Assertions to the specific samplers they are intended for.
🎯 Practice task
Add assertions to your test plan and observe what happens when they fail.
- Add a Response Assertion to your main HTTP Request sampler. Set Field = Response Code, Rule = Equals, Pattern =
200. Run againsttest.k6.io— confirm it passes (green). - Change the assertion pattern to
999. Run again — the sample should now appear red. Check the Assertion Results listener to see the failure message. - Change the pattern back to
2\d{2}with Rule = Matches. Verify this accepts the actual response code. - Add a Duration Assertion with 100ms limit to the same sampler. Run — it will almost certainly fail (network latency alone exceeds 100ms). Change to 5000ms and confirm it passes. This exercises the Duration Assertion without requiring a server that is actually too slow.
- Add a Size Assertion with comparison
> 0. Run against an endpoint that returns a body. Confirm it passes. Manually target a path that returns 204 No Content (if your test server supports one) and observe the Size Assertion with= 0.