Reference

Assertion Operators

Complete reference of all assertion operators for assert.body, assert.status, and assert.headers.

Body assertion operators

Keyed by JSONPath in assert.body. Multiple operators on the same path combine with AND.

Operator Description Example
eq Exact equality (same as bare literal) { eq: "Alice" }
not_eq Not equal { not_eq: "Bob" }
type Assert JSON type: string, number, boolean, array, object, null { type: string }
contains Substring in strings, element in arrays { contains: "sub" }
not_contains Inverse of contains { not_contains: "x" }
starts_with String prefix { starts_with: "usr_" }
ends_with String suffix { ends_with: ".com" }
matches Regex match { matches: "^[a-z]+$" }
exists Assert field presence or absence { exists: true }
not_empty Non-empty string, array, or object { not_empty: true }
empty / is_empty Value is empty (empty strings, arrays, objects, null) { empty: true }
length Exact length of string or array { length: 5 }
length_gt Length greater than { length_gt: 2 }
length_gte Length greater than or equal { length_gte: 3 }
length_lte Length less than or equal { length_lte: 10 }
gt Greater than (numeric) { gt: 0 }
gte Greater than or equal { gte: 100 }
lt Less than (numeric) { lt: 1000 }
lte Less than or equal { lte: 500 }
is_uuid Valid UUID (any version) { is_uuid: true }
is_uuid_v4 Valid UUID v4 { is_uuid_v4: true }
is_uuid_v7 Valid UUID v7 { is_uuid_v7: true }
is_date Valid ISO date or datetime string { is_date: true }
is_ipv4 Valid IPv4 address { is_ipv4: true }
is_ipv6 Valid IPv6 address { is_ipv6: true }
bytes Raw response byte length (for "$" path) { bytes: 1024 }
sha256 SHA-256 hex digest of response body { sha256: "abc..." }
md5 MD5 hex digest of response body { md5: "def..." }
exists_where / contains_object Array contains at least one object matching a predicate { exists_where: { "name": "Alice" } }
not_exists_where Array contains no object matching a predicate { not_exists_where: { "status": "deleted" } }

Status assertions

Form Example Description
Exact integer status: 200 Match a single status code
Shorthand range status: "2xx" Match any 2xx, 4xx, or 5xx status
List status: { in: [200, 201, 204] } Match any of the listed codes
Range status: { gte: 200, lt: 300 } Numeric comparison operators (gte, gt, lte, lt, in)

Header assertions

Form Example Description
Exact content-type: "application/json" Match header value exactly
Substring content-type: { contains: "json" } Substring match
Regex x-request-id: { matches: "^[a-f0-9-]+$" } Regex match

Duration assertions

Example Description
duration: "< 500ms" Step completed in under 500ms
duration: "<= 1s" Step completed in at most 1 second
duration: "> 200ms" Step took more than 200ms

Redirect assertions

Field Example Description
redirect.url redirect.url: "https://final.example.com" Expected final URL after redirects
redirect.count redirect.count: 2 Expected number of redirects followed

Plain text / HTML responses

Use the root path "$" to assert on the entire response body as a string:

assert:
  status: 200
  body:
    "$": "expected plain text response"

Non-JSON responses (plain text, HTML) are preserved as JSON strings in structured output.

Multiple operators (AND)

Operators on the same JSONPath combine with AND:

assert:
  body:
    "$.email":
      type: string
      contains: "@"
      not_empty: true
      matches: "^[a-z@.]+$"

Literal exact match

A bare value (not wrapped in an operator map) is treated as eq:

# These are equivalent:
"$.name": "Alice"
"$.name": { eq: "Alice" }