Assertions let you validate every aspect of an HTTP response — status codes, headers, body content, response times, and more. hitspec provides 26 operators grouped into six categories.
Assertion Block Syntax
Wrap assertions in >>> and <<< markers:
GET {{baseUrl}}/users
>>>
expect status 200
expect body type array
expect body[ 0 ].id exists
expect duration < 500
<<<
Each line inside the block follows this pattern:
expect <subject> <operator> <value>
When the operator is ==, you can omit it:
>>>
expect status 200 # shorthand for: expect status == 200
expect status == 200 # explicit form
<<<
Assertion Subjects
Subject Description Example statusHTTP status code expect status 200durationResponse time in milliseconds expect duration < 1000header <name>Response header value expect header Content-Type contains jsonbodyFull response body (as string) expect body contains "success"body.<path>JSON path into body expect body.user.name == "John"body[n]Array index expect body[0].id existsjsonpath $.<path>JSONPath expression expect jsonpath $.users[0].id exists
Equality and Comparison
Compare values using standard comparison operators.
Operator Syntax Description ==expect status == 200Equals !=expect body.error != nullNot equals >expect body.count > 0Greater than >=expect body.count >= 1Greater than or equal <expect duration < 1000Less than <=expect duration <= 500Less than or equal
### Verify response timing and pagination
GET {{baseUrl}}/users?page=1&limit=20
>>>
expect status == 200
expect duration < 500
expect body.total > 0
expect body.page == 1
expect body.perPage >= 20
<<<
Use expect status 200 as shorthand for expect status == 200. The == operator is implied when omitted.
String Operators
Match, search, and compare string values.
Operator Syntax Description containsexpect body contains "success"Contains substring !containsexpect body !contains "error"Does not contain substring startsWithexpect body.url startsWith "https"Starts with prefix endsWithexpect body.email endsWith ".com"Ends with suffix matchesexpect body.id matches /^\d+$/Matches regular expression
### Check user profile fields
GET {{baseUrl}}/users/1
>>>
expect status 200
expect body.email endsWith "@example.com"
expect body.website startsWith "https"
expect body.bio !contains "<script>"
expect body.phone matches /^\+?[ \d\s\-() ]+$/
<<<
Regular expressions in matches are enclosed in forward slashes: /pattern/. The pattern uses Go’s regexp syntax.
Existence and Type
Check whether values exist and validate their types.
Operator Syntax Description existsexpect body.id existsValue is present and not null !existsexpect body.error !existsValue is absent or null typeexpect body.items type arrayCheck value type
Supported types for the type operator: null, boolean, number, string, array, object.
### Validate response structure
GET {{baseUrl}}/users/1
>>>
expect status 200
expect body.id exists
expect body.name type string
expect body.age type number
expect body.active type boolean
expect body.tags type array
expect body.address type object
expect body.deletedAt !exists
<<<
Length and Arrays
Validate array lengths and check array contents.
Operator Syntax Description lengthexpect body.items length 10Length equals exact value length >expect body.items length > 0Length greater than length >=expect body.items length >= 1Length greater than or equal length <expect body.items length < 100Length less than length <=expect body.items length <= 50Length less than or equal includesexpect body.tags includes "admin"Array contains value !includesexpect body.tags !includes "test"Array does not contain value inexpect status in [200, 201, 204]Value is one of the listed values !inexpect status !in [400, 404, 500]Value is not one of the listed values eachexpect body.items each type objectApply assertion to every element
### Validate paginated list
GET {{baseUrl}}/users?role=admin
>>>
expect status 200
expect body.users length > 0
expect body.users length <= 100
expect body.users each type object
<<<
The each Operator
each applies an assertion to every element in an array. It is useful for validating the shape of list responses:
>>>
expect body.users each type object
<<<
The in Operator
in checks whether a value is a member of a set. List values in square brackets:
>>>
expect status in [ 200 , 201 ]
expect body.role in [ "admin" , "editor" , "viewer" ]
<<<
The includes Operator
includes checks whether an array contains a specific value:
>>>
expect body.permissions includes "read"
expect body.permissions includes "write"
expect body.permissions !includes "superadmin"
<<<
Schema Validation
Validate the entire response body against a JSON Schema file.
Operator Syntax Description schemaexpect body schema ./schema.jsonValidate against JSON Schema
GET {{baseUrl}}/users/1
>>>
expect status 200
expect body schema ./schemas/user.json
<<<
Where schemas/user.json contains a standard JSON Schema:
{
"$schema" : "http://json-schema.org/draft-07/schema#" ,
"type" : "object" ,
"required" : [ "id" , "name" , "email" ],
"properties" : {
"id" : { "type" : "integer" },
"name" : { "type" : "string" , "minLength" : 1 },
"email" : { "type" : "string" , "format" : "email" },
"role" : { "enum" : [ "admin" , "user" , "guest" ] }
}
}
Schema file paths are resolved relative to the .http file that references them.
Snapshot Testing
Compare the response body against a previously saved baseline. On first run, the snapshot is created. On subsequent runs, the response is compared against it.
Operator Syntax Description snapshotexpect body snapshot "name"Compare against saved snapshot
GET {{baseUrl}}/config
>>>
expect status 200
expect body snapshot "app-config"
<<<
Snapshots are stored in a __snapshots__ directory next to your test file. Update them when the response intentionally changes:
hitspec run tests/ --update-snapshots
Snapshot testing works well for responses that should remain stable over time, such as configuration endpoints or reference data.
Combining Assertions
A single assertion block can mix operators from any category:
### Full response validation
POST {{baseUrl}}/orders
Content-Type : application/json
{
"productId" : "prod-123" ,
"quantity" : 2
}
>>>
expect status 201
expect duration < 1000
expect header Content-Type contains json
expect body.id exists
expect body.id type string
expect body.status == "pending"
expect body.items length 2
expect body.items each type object
expect body.total > 0
expect body schema ./schemas/order.json
<<<
Assert on response headers using the header <name> subject:
>>>
expect header Content-Type contains "application/json"
expect header X-Request-Id exists
expect header X-RateLimit-Remaining > 0
expect header Cache-Control contains "no-cache"
<<<
Testing Error Responses
Assertions are equally useful for verifying error behavior:
401 Unauthorized
404 Not Found
400 Validation Error
### Missing authentication
GET {{baseUrl}}/admin/users
>>>
expect status 401
expect body.error exists
expect body.message contains "unauthorized"
<<<