Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gatling/gatling.io-doc/llms.txt

Use this file to discover all available pages before exploring further.

Checks are Gatling’s mechanism for verifying that a response meets your expectations and, optionally, extracting values from it to reuse in later requests. Every check follows the same pipeline: choose a check type (what part of the response to inspect), apply an extractor (which occurrence to capture), optionally transform the captured value, validate it against an expected result, and save it into the session. Checks are attached to requests via the .check() method and can be combined freely.

How Checks Are Attached

// single check
http("Gatling").get("https://gatling.io")
  .check(status().is(200));

// multiple checks at once
http("Gatling").get("https://gatling.io")
  .check(
    status().not(404),
    status().not(500)
  );
The check pipeline steps are:
  1. Check type — what to inspect
  2. Extracting — which occurrence(s) to capture
  3. Transforming — optional value transformation
  4. Validating — assert a condition on the value
  5. Naming — optional custom error message label
  6. Saving — store the result in the session

Check Types

Response Time

Java
.check(responseTimeInMillis().lte(100))
Returns the total time in milliseconds from the start of sending the request to the end of receiving the response.

Body Checks

// full body as String
.check(bodyString().is("{\"foo\": \"bar\"}"))

// full body as byte array
.check(bodyBytes().is("{\"foo\": \"bar\"}".getBytes(StandardCharsets.UTF_8)))

// body length in bytes (no array allocation)
.check(bodyLength().is(1024))

// substring search (efficient, no regex overhead)
.check(substring("expected"))
.check(substring("Error:").notExists())
.check(substring("foo").findAll().saveAs("indices"))
.check(substring("foo").count().saveAs("counts"))

regex — Regular Expression

.check(regex("<td class=\"number\">"))
.check(regex("<td class=\"number\">ACC#{account_id}</td>"))
.check(regex("/private/bank/account/(ACC[0-9]*)/operations.html"))

// multiple capture groups (Java)
.check(regex("foo(.*)bar(.*)baz").captureGroups(2))

jsonPath — JSONPath Queries

.check(jsonPath("$..foo.bar[2].baz"))
.check(jsonPath("$..foo.bar[#{index}].baz"))      // Gatling EL
.check(jsonPath(session -> "$..foo.bar[" + session.getInt("session") + "].baz"))

// typed extraction
.check(jsonPath("$.foo").ofString())
.check(jsonPath("$.foo").ofInt())
.check(jsonPath("$.foo").ofBoolean())
.check(jsonPath("$.foo").ofDouble())
.check(jsonPath("$.foo").ofList())    // JSON array
.check(jsonPath("$.foo").ofMap())     // JSON object

// integer comparison
.check(jsonPath("$.foo").ofInt().is(1))

jmesPath — JMESPath Queries

JMESPath has a formal grammar and a compliance test suite, making it more predictable than JSONPath for complex expressions.
.check(jmesPath("foo.bar[2].baz"))
.check(jmesPath("foo.bar[#{index}].baz"))

// typed extraction
.check(jmesPath("foo").ofString())
.check(jmesPath("foo").ofInt())
.check(jmesPath("foo").ofList())
.check(jmesPath("foo").ofMap())

.check(jmesPath("foo").ofInt().is(1))

xpath — XPath Queries (XML)

// document without namespaces
.check(xpath("//input[@id='text1']/@value"))

// document with namespaces (prefix map is mandatory)
.check(xpath("//foo:input[@id='text1']/@value", Map.of("foo", "http://foo.com")))
XPath only works on well-formed XML. For HTML documents, use the css selector instead.

css — CSS Selectors (HTML)

.check(css("#foo"))
.check(css("##{id}"))                        // Gatling EL
.check(css(session -> "#" + session.getString("id")))
.check(css("article.more a", "href"))        // select an attribute

form — HTML Form Capture

Captures all input values within a form tag into a Map.
.check(form("myForm"))

Checksums (md5, sha1)

Verify the integrity of a downloaded resource without loading the entire body into memory.
.check(md5().is("abc123..."))
.check(sha1().is("def456..."))

Extractors

Extractors filter which occurrence(s) of a multi-valued check result to capture.
If you omit the extraction step, Gatling performs an implicit find (the first occurrence).
ExtractorDescription
find() / find(n)Capture the first occurrence (or the nth, 0-based).
findAll()Capture all occurrences as a list.
findRandom() / findRandom(n, failIfLess)Capture a random occurrence or n random occurrences.
count()Capture the total number of occurrences.
.check(jsonPath("$.foo").find())
.check(jsonPath("$.foo").find(1))       // second occurrence
.check(jsonPath("$.foo").findAll())
.check(jsonPath("$.foo").findRandom())
.check(jsonPath("$.foo").findRandom(3, true)) // fail if fewer than 3 matches
.check(jsonPath("$.foo").count())

Transforming

Use transform or withDefault to process the extracted value before validation or saving.
.check(jsonPath("$.foo").transform(string -> string + "bar"))

.check(jsonPath("$.foo")
  .transformWithSession((string, session) -> string + session.getString("bar")))

.check(jsonPath("$.foo").withDefault("defaultValue"))

Validators

If you omit the validation step, Gatling performs an implicit exists check.
ValidatorDescription
is(value)Exact equality.
not(value)Must not equal.
isNull()Value must be null.
notNull()Value must not be null.
exists()Value must exist.
notExists()Must not have matched.
in(values...)Value must be in the provided set.
optional()Allows the target to be missing; subsequent steps (including saveAs) are skipped if nothing was captured.
validate(name, fn)Custom validator function.
.check(jmesPath("foo").is("expected"))
.check(jmesPath("foo").isEL("#{expected}"))   // EL overload
.check(jmesPath("foo").not("unexpected"))
.check(jmesPath("foo").isNull())
.check(jmesPath("foo").notNull())
.check(jmesPath("foo").exists())
.check(jmesPath("foo").notExists())
.check(jmesPath("foo").in("value1", "value2"))
.check(jmesPath("foo").in(List.of("value1", "value2")))

// custom validator
.check(jmesPath("foo").ofDouble().validate(
  "is +/- 0.1",
  (actual, session) -> {
    double expected = session.getDouble("expected");
    if (Math.abs(actual - expected) > 0.1) {
      throw new RuntimeException("Value is not within 0.1 margin");
    }
    return actual;
  }
))

Naming Checks

Give a check a custom label that appears in error messages when the check fails:
.check(jmesPath("foo").name("My custom error message"))

Saving Check Results

Use saveAs to store the extracted and validated value into the virtual user’s Session for reuse in subsequent requests. Saving only occurs if the check succeeds.
.check(jmesPath("foo").saveAs("key"))

Conditional Checks (checkIf)

Run a check only when a condition holds. Use checkIf instead of check when the check should be conditional.
// EL string condition
.checkIf("#{bool}").then(jmesPath("foo"))

// function condition
.checkIf(session -> session.getString("key").equals("executeCheck")).then(jmesPath("foo"))

Putting It All Together

Here is a complete example combining multiple check types on a single request:
.check(
  // verify HTTP status is 200
  status().is(200),

  // status is in an acceptable range
  status().in(200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210),

  // body contains exactly 5 https links
  regex("https://(.*)").count().is(5),

  // the two https hosts in order
  regex("https://(.*)/.*").findAll().is(List.of("www.google.com", "gatling.io")),

  // a second occurrence of "someString" exists
  substring("someString").find(1).exists(),

  // "someString" does NOT appear
  substring("someString").notExists()
)

Build docs developers (and LLMs) love