Docs
Assertions (Compact DSL)
Master the Compact DSL for powerful response validation
Assertions (Compact DSL)
Learn Quadrastack's powerful inline assertion syntax for validating HTTP responses.
Overview
The expect field validates responses using our Compact DSL - a concise, readable syntax for expressing assertions. Unlike traditional testing frameworks that require verbose code, the Compact DSL lets you write assertions inline in YAML.
Basic Structure
requests:
get-users:
method: GET
url: https://api.example.com/users
expect: # Assertions start here
status: 200 # Status code assertion
headers: # Header assertions
Content-Type: contains application/json
body: # Body assertions (JSONPath)
$.length: "> 0"
$.is: exists
responseTime: "< 500ms" # Response time assertion
Operators Reference
Existence Operators
exists
Value must be present (not nil or missing).
expect:
body:
$.id: exists
$.user.email: exists
!exists
Value must NOT be present (nil or missing).
expect:
headers:
X-Internal-Debug: "!exists" # Should not be in response
body:
$.error: "!exists"
!empty
Value must not be empty string.
expect:
body:
$.name: !empty
$.description: !empty
String Matching
contains "text"
String must contain the substring.
expect:
headers:
Content-Type: contains application/json
Set-Cookie: contains session=
body:
$.message: contains success
$.url: contains https://
Note: Quotes around the text are optional but recommended for clarity.
!contains "text"
String must NOT contain the substring.
expect:
body:
$.message: !contains error
$.response: !contains failed
matches "regex"
String must match the regular expression pattern.
expect:
body:
$.email: matches "^[\\w.]+@[\\w.]+\\.[\\w]+$"
$.uuid: matches "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
$.phone: matches "^\\+?[0-9]{10,15}$"
$.date: matches "^\\d{4}-\\d{2}-\\d{2}$"
Important: Escape backslashes in YAML (\\ instead of \).
Numeric Comparisons
> N - Greater Than
expect:
body:
$.count: "> 0"
$.price: "> 99.99"
$.stock: "> 10"
>= N - Greater Than or Equal
expect:
status: ">= 200" # Any success status
body:
$.total: ">= 1"
$.rating: ">= 4.0"
< N - Less Than
expect:
body:
$.age: "< 100"
$.discount: "< 50"
<= N - Less Than or Equal
expect:
body:
$.quantity: "<= 1000"
$.percentage: "<= 100"
Type Checks
type <type>
Value must be of the specified JSON type.
Supported types:
stringnumberboolean(orbool)arrayobjectnull
expect:
body:
$.id: type number
$.name: type string
$.active: type boolean
$.tags: type array
$.metadata: type object
$.deletedAt: type null
Length Checks
Works on strings and arrays.
length N - Exact Length
expect:
body:
$.code: length 6 # Exactly 6 characters
$.items: length 10 # Exactly 10 array items
length > N - Length Greater Than
expect:
body:
$.description: length > 10
$.results: length > 0
length >= N - Length Greater Than or Equal
expect:
body:
$.password: length >= 8
$.items: length >= 1
length < N - Length Less Than
expect:
body:
$.title: length < 100
$.tags: length < 20
length <= N - Length Less Than or Equal
expect:
body:
$.summary: length <= 280 # Tweet length
$.choices: length <= 5
List Membership
in [val1, val2, val3]
Value must be one of the listed values.
expect:
body:
$.status: in [active, pending, completed]
$.role: in [admin, user, guest]
$.priority: in [high, medium, low]
Exact Match
Plain value for exact equality.
expect:
status: 200 # Exact status code
body:
$.status: "success" # Exact string match
$.count: 42 # Exact number
$.enabled: true # Exact boolean
Array of Values (Any Of)
Match if value equals any of the listed values.
expect:
status: [200, 201] # Status is 200 OR 201
body:
$.type: [user, admin] # Type is "user" OR "admin"
Assertion Targets
Status Code
Validate HTTP status codes.
expect:
status: 200 # Exact match
status: [200, 201] # Any of these
status: ">= 200" # Range check
status: "< 400" # Less than 400
Common patterns:
# Success (2xx)
status: ">= 200"
status: "< 300"
# Client error (4xx)
status: ">= 400"
status: "< 500"
# Created
status: 201
# No content
status: 204
# Not found
status: 404
Headers
Validate response headers.
expect:
headers:
# Exact match
Content-Type: application/json
# Contains
Content-Type: contains application/json
Set-Cookie: contains session=
# Exists
X-Request-ID: exists
X-RateLimit-Remaining: exists
# Doesn't exist
X-Debug-Info: "!exists"
# Regex match
Date: matches "^[A-Za-z]{3}, \\d{2} [A-Za-z]{3} \\d{4}"
# Not empty
Authorization: !empty
Note: Header names are case-insensitive in HTTP but case-sensitive in assertions.
Body (JSONPath)
Validate JSON response bodies using JSONPath expressions.
JSONPath Syntax Quick Reference
| Expression | Meaning | Example |
|---|---|---|
$ | Root object | $: type object |
$.field | Top-level field | $.id: exists |
$.nested.field | Nested field | $.user.email: !empty |
$[0] | Array index | $[0].id: exists |
$.array[0] | Named array index | $.items[0].name: !empty |
$.array.length | Array length | $.items.length: "> 0" |
Common Body Assertions
expect:
body:
# Root type
$: type object
$: type array
# Field existence
$.id: exists
$.user: exists
$.error: "!exists"
# Field values
$.status: "success"
$.code: 200
$.active: true
# Nested fields
$.user.id: exists
$.user.email: matches "^\\w+@\\w+\\.\\w+$"
$.user.name: !empty
# Arrays
$.items: type array
$.items.length: "> 0"
$.items.length: "<= 100"
$.items[0].id: exists
$.items[0].name: !empty
# Type checks
$.id: type number
$.tags: type array
$.metadata: type object
# Numeric comparisons
$.count: "> 0"
$.total: ">= 100"
$.price: "< 1000"
# String matching
$.message: contains success
$.url: contains https://
$.code: length 6
Response Time
Validate response time performance.
expect:
responseTime: "< 500ms" # Less than 500 milliseconds
responseTime: "< 1s" # Less than 1 second
responseTime: "<= 2s" # At most 2 seconds
responseTime: "< 100ms" # Very fast
Supported units:
ms- millisecondss- secondsm- minutes
Complete Examples
Response Body Validation
Validate complex nested JSON structures and arrays:
requests:
get-user-data:
expect:
status: 200
headers:
Content-Type: contains application/json
body:
# Root array validation
$: type array
$.length: "> 0"
# Item validation
$[0].id: 123
$[0].email: matches "^[\\w.]+@[\\w.]+\\.[\\w]+$"
$[0].name: !empty
$[0].role: in [user, admin, guest]
# Nested object validation
$[0].profile: type object
$[0].profile.age: "> 18"
Error Response
requests:
unauthorized:
method: GET
url: https://api.example.com/admin
expect:
status: 401
body:
$.error: "unauthorized"
$.message: !empty
$.code: 401
$.data: "!exists" # No data in error response
Create Resource
requests:
create-user:
method: POST
url: https://api.example.com/users
body: |
{
"name": "John Doe",
"email": "john@example.com"
}
expect:
status: [201, 200] # Accept either
headers:
Location: exists
Location: contains /users/
body:
$.id: exists
$.id: type number
$.name: "John Doe"
$.email: "john@example.com"
$.createdAt: exists
$.createdAt: matches "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"
Pagination
requests:
paginated-list:
method: GET
url: https://api.example.com/items?page=1&limit=20
expect:
status: 200
body:
$.items: type array
$.items.length: ">= 1"
$.items.length: "<= 20"
$.pagination: type object
$.pagination.page: 1
$.pagination.limit: 20
$.pagination.total: "> 0"
$.pagination.hasNext: type boolean
Advanced Patterns
Multiple Conditions
Combine multiple assertions on the same field:
expect:
body:
# Multiple assertions as a list
$.price:
- type number
- "> 0"
- "< 10000"
$.title:
- type string
- !empty
- length >= 3
- length <= 100
Conditional Fields
Check if optional fields are valid when present:
expect:
body:
# Required field
$.id: exists
# Optional field - if present, must be valid
# (Use workflows to conditionally check)
For complex conditional logic, use workflows with conditional steps.
Deep Nesting
expect:
body:
$.user.profile.settings.notifications.email: true
$.data.items[0].metadata.tags[0]: !empty
Common Pitfalls
1. Escaping Regex
❌ Wrong:
$.email: matches "^\w+@\w+\.\w+$"
✅ Correct:
$.email: matches "^\\w+@\\w+\\.\\w+$"
YAML requires escaping backslashes.
2. Quotes for Operators
Some operators need quotes in YAML:
❌ Wrong:
$.count: > 0 # Parsed as YAML anchor
$.status: !exists # Parsed as YAML tag
✅ Correct:
$.count: "> 0"
$.status: "!exists"
3. Type vs Value
❌ Wrong:
$.active: "true" # String "true", not boolean
✅ Correct:
$.active: true # Boolean true
$.active: type boolean # Check type
4. Array Length
❌ Wrong:
$.items: "> 0" # Comparing array to number
✅ Correct:
$.items.length: "> 0"
See Also
- Requests - Define HTTP requests
- Workflows - Chain requests
- Templating - Dynamic assertions
- Tutorials - Step-by-step examples