skip to content

In JMeter's Response Assertion, what do the Contains, Matches, Equals and Substring rules each test?

level: juniorimportance: must knowfreq 78%

answer

  1. Four rules, split into two families
  2. Two compile a pattern, two do not
  3. Whole field versus found anywhere
  4. Plain rules are case-sensitive text
  5. No slashes around the pattern

basics

~10 s

Contains and Matches read the pattern as a Perl5-style regular expression: Contains needs it found somewhere in the field, Matches needs it to span the whole field. Equals and Substring are plain, case-sensitive text.

solid answer

~40 s

The **Pattern Matching Rules** radio group on a Response Assertion picks one of four rules, and JMeter's manual splits them into two families. `Contains` and `Matches` compile the pattern as a **Perl5-style regular expression**: `Contains` passes when the expression is found anywhere in the selected field, `Matches` passes only when it matches that field from first character to last. `Equals` and `Substring` are **plain text and case-sensitive**: `Equals` is an exact comparison of the whole field, `Substring` a containment test, and neither interprets `.`, `$` or `[` as metacharacters. The rule is a property of the element, not of an individual pattern, so every entry in *Patterns to Test* is evaluated under the same rule. Patterns are written without enclosing delimiters — `Price: \d+`, never `/Price: \d+/`.

code

xml · 8 lines
xml
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assertion" enabled="true">
  <collectionProp name="Asserion.test_strings">
    <stringProp name="-1139173792">&lt;/html&gt;</stringProp>
  </collectionProp>
  <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
  <boolProp name="Assertion.assume_success">false</boolProp>
  <intProp name="Assertion.test_type">2</intProp>
</ResponseAssertion>

go deeper

for a junior

Recall the four names and which two are regular expressions. Say plainly that Contains and Substring look for the pattern anywhere, while Matches and Equals compare the whole field.

for a middle

Explain the mechanics: Contains maps to a regex find, Matches to a whole-field regex match, Equals to string equality and Substring to string containment, all case-sensitive, with multi-line regex semantics by default.

for a senior

Show you pick the rule from the shape of the evidence, not habit. Talk about (?i) and (?s) overrides, about a Matches pattern silently failing every sample, and about the Response was null result on an empty field.

for a principal

Own the convention. Decide whether plans in your organisation express content checks as plain Substring patterns that anyone can read, or as regular expressions, and say what that choice costs in review and in false failures.

## The three fields that define a Response Assertion A **Response Assertion** is configured by three things, and the matching rule is only one of them: - **Field to Test** — which part of the request or response is read (`Text Response`, `Response Code`, `Response Message`, `Response Headers`, `Request Headers`, `Request Data`, `URL Sampled`, `Document (text)`). - **Pattern Matching Rules** — one of `Contains`, `Matches`, `Equals`, `Substring`, plus the `Not` and `Or` modifiers. - **Patterns to Test** — a list of pattern strings, all evaluated under the one rule chosen above. A Response Assertion you add in the GUI opens with **Text Response** as the field and **Substring** as the rule, with `Not`, `Or` and `Ignore Status` all clear. ## The regular-expression pair: Contains and Matches Both compile the pattern as a Perl5-style regular expression, and they differ only in how much of the field the expression has to account for: - `Contains` — passes when the expression is found **somewhere** in the field. Internally this is the matcher's *contains* operation. - `Matches` — passes only when the expression matches the field **end to end**. Internally this is the matcher's *matches* operation. The pattern carries no enclosing delimiters. Write `Price: \d+`, not `/Price: \d+/`. Matching is multi-line by default, which trips people up: - `.` does **not** match a newline, but `\s` does. - `^` and `$` match at the start and end of *any* line inside the field, not just of the whole field. - Case is significant. The extended syntax overrides those defaults inline, anywhere in the expression and until overridden again: | Prefix | Effect | |---|---| | `(?i)` | ignore case | | `(?s)` | treat the target as a single line, so `.` matches a newline | | `(?is)` | both of the above | ## The plain-text pair: Equals and Substring Neither of these compiles anything. - `Equals` — a case-sensitive comparison of the **entire field** against the pattern string. - `Substring` — a case-sensitive containment test. Because no expression is compiled, `$1.00`, `total.amount` and `data[0]` are all literal text under these two rules. That is the reason to reach for them when the thing you are looking for is a fixed string that happens to contain metacharacters. ## The four rules side by side | Rule | Pattern is | Passes when | |---|---|---| | `Contains` | Perl5 regular expression | the expression is found anywhere in the field | | `Matches` | Perl5 regular expression | the expression matches the whole field | | `Equals` | plain, case-sensitive text | the field equals the pattern exactly | | `Substring` | plain, case-sensitive text | the field contains the pattern | ## What the rule does not decide Four things stay outside the radio group, and mixing them up is the usual source of confusion: 1. **Which field is read.** That is *Field to Test*. A `Substring` rule against `Response Code` and against `Text Response` are entirely different checks. 2. **How several patterns combine.** That is the `Not` and `Or` modifiers. 3. **Whether a passing assertion can rescue a red sample.** It cannot; the assertion's verdict is combined with the status the sample already carries, and only the `Ignore Status` checkbox resets that status first. 4. **What an empty field does.** If the selected field is empty, the assertion fails with the message `Response was null` — unless `Not` is ticked, in which case an empty field is treated as a pass. ## A worked example: the confirmation body that must carry an order id A checkout sampler returns `200 OK`, so JMeter marks it green on the status alone. The plan needs it red when the confirmation body comes back without an `orderId`. All four rules can express something here, and only two of them express the right thing: - `Substring` with the pattern `"orderId"` — passes when that literal text appears anywhere in the body. Simple, and the quotes and colon are literal. - `Contains` with `"orderId"\s*:\s*"[0-9a-f-]+"` — passes when the field is not merely present but carries a value shaped like an id. - `Matches` with `"orderId"` — **fails on every response**, because the whole body is never exactly that string. This is the single most common misconfiguration of the element. - `Equals` with `"orderId"` — fails for the same reason: it compares the whole body. So `Matches` and `Equals` are whole-field rules and `Contains` and `Substring` are find-it-anywhere rules; that axis, not the regex-versus-plain axis, is what usually decides which one a check needs.

  • You need to check for the literal text $12.50 in a response body. Which rule would you pick and why?
    `Substring`. It is a plain, case-sensitive containment test, so `$` and `.` are ordinary characters. Under `Contains` the same string is a regular expression in which `$` anchors to the end of a line and `.` matches any character, so it would either fail or match text you did not intend.
  • A Response Assertion has three patterns and the second one fails. Are the remaining patterns still evaluated?
    No. With the patterns combined by AND — the default, with `Or` unticked — the assertion stops at the first pattern that fails, records that pattern's failure message and returns. The third pattern is never tested, so its result never appears in the failure text.
  • Does a Response Assertion behave differently if you split its three patterns into three separate assertions?
    No, provided the other settings match. JMeter's manual states there is no difference between one assertion with several patterns and several assertions with one pattern each. The exception is `Ignore Status`, which resets the sample's status and so must only sit on the first assertion in the sequence.

saying these in an interview costs you the question

  • Thinking Contains and Substring differ only in speed
  • Using Matches for a fragment of a large body
  • Writing the pattern wrapped in forward slashes
  • Expecting Equals or Substring to honour regex metacharacters
  • Assuming the dot matches newlines by default
  • Believing a passing assertion turns a red sample green