ResponseValidate
Validate HTTP API response correctness
ResponseValidate lets you validate both HTTP status code and response content in a single step, supporting both DataTable and JSON formats.
Basic Usage
Then create todo(201) response, with table:
| >todo1.id | userId | title | completed |
| <todoId | $Alice.id | Buy milk | false |This instruction will:
- Validate HTTP status code is
201 - Validate field values in the response JSON
- Extract
todoIdfrom response and store in variabletodo1.id
Two Formats
| Format | Use Case |
|---|---|
| DataTable | Field-level validation, supports variable extraction |
| DocString JSON | Complete JSON structure validation |
JSON format note: Symbol system expressions (
$variables,&CAS constraints,@time symbols,>/<extraction keys) must NOT be placed inside JSON string quotes"", otherwise they are treated as plain strings.{ "todoId": $todo1.id } // ✅ Correct: symbol outside quotes { "todoId": "$todo1.id" } // ❌ Wrong: symbol wrapped in quotes, treated as plain string
DataTable Format
Then get todo(200) response, with table:
| todoId | title | completed |
| $todo1.id | Buy milk | false |JSON Format
Then get todo(200) response, with JSON:
"""json
{
"todoId": $todo1.id,
"title": "Buy milk",
"completed": false
}
"""Nested Paths
Supports dot notation and array indexing for nested JSON validation:
Then get order(200) response, with table:
| data.order.id | data.items[0].name | data.items[1].name |
| $order1.id | Product A | Product B |Escaping Keys Containing .
When a JSON key itself contains a . character, use ["..."] bracket notation to prevent it from being split into nested levels:
Then get settings(200) response, with table:
| content.["btn.save"] | content.["btn.cancel"] |
| Save | Cancel |Response Header Validation
Use the H: prefix to validate HTTP Header values in the response:
# DataTable
Then create resource(201) response, with table:
| H:Location | id |
| /api/resources/1 | 1 |
# JSON
Then create resource(201) response, with JSON:
"""json
{
H"Location": "/api/resources/1",
"id": 1
}
"""Bare Value and Top-Level Array Response Body
When API returns bare values (e.g., true, 42) or top-level arrays, use B: to mark the entire response body:
# Bare value validation
Then get resource status(200) response, with JSON:
"""json
{ B: true }
"""
# Top-level array validation + Response Header
Then batch create resources(201) response, with JSON:
"""json
{
H"X-Total-Count": "2",
B: [
{ "id": 1, "name": "Resource A" },
{ "id": 2, "name": "Resource B" }
]
}
"""Variable Extraction
> and < must be paired vertically in the same column: the header holds the variable name (>), and the row holds the source field in the response (<).
Then login(200) response, with table:
| >userToken | >userId |
| <token | <id |After execution:
userToken= value oftokenfrom responseuserId= value ofidfrom response
Variable Reference
Use $variable to reference previously stored variables for comparison:
Then get user(200) response, with table:
| userId | name |
| $Alice.id | Alice |CAS Constraint Validation
Use CAS constraints for flexible validation:
Then get order(200) response, with table:
| orderId | amount | status | createdAt |
| &isNum | >(1000) | &oneOf("pending","active") | &sameTime("2026-01-27T10:00:00") |Common constraints:
&isNum,&isStr,&isNull— type checks>(),<(),&between()— numeric ranges&contains(),&startsWith()— string matching&sameTime()— time comparison
See CAS Symbols for the complete constraint list.
Validation Flow
ResponseValidate executes four validation layers in sequence:
- HTTP Status Code: Fails immediately if status code doesn't match
- JSON Structure Comparison: Recursively compares JSON nodes
- Value-Level Validation: Numeric comparison, CAS constraints, variable resolution
- Schema Validation: Checks types against API Spec definitions
Error Handling
Lint Phase
| Error | Description |
|---|---|
| Field not found | Field name not found in Response Schema |
| Extract field not found | Field specified with < not found in Response Schema |
Runtime
| Error | Description |
|---|---|
| Status code mismatch | Actual status code differs from expected |
| Field value mismatch | Field value doesn't match expected |
| JSON structure mismatch | Array length or object fields don't match |
| Schema validation failed | Doesn't conform to API Spec Schema definition |
Complete Example
Feature: Update Todo
Background:
# TimeControl instruction (see TimeControl docs)
Given current time is "2026-01-27T10:00:00"
# EntitySetup instruction (see EntitySetup docs)
Given prepare a user, with table:
| >Alice.id | name | email | status |
| <userId | Alice | alice@example.com | ACTIVE |
Example: Update todo title
# ApiCall instruction (see ApiCall docs)
When (UID="$Alice.id") create todo, call table:
| >todo1.id | title |
| <todoId | Buy milk |
When (UID="$Alice.id") update todo, call table:
| P:todoId | title |
| $todo1.id | Buy soy milk |
# ResponseValidate instruction — validate status code and response fields
# $todo1.id: references a previously extracted variable
# &sameTime(...): CAS time constraint, validates time value
Then update todo(200) response, with table:
| todoId | title | completed | updatedAt |
| $todo1.id | Buy soy milk | false | &sameTime("2026-01-27T10:00:00") |