test.json Reference
The test.json file defines all HTTP test cases to be executed against your service, including paths, methods, expected status codes, and header validations.
Overview
Located at .httptests/test.json, this file specifies:
- Host-based test organization
- HTTP methods (GET, POST, PUT, DELETE, etc.)
- Expected status codes
- Response header validations
- Request header forwarding validations
- Collection headers for reuse
Basic Structure
{
"collectionHeaders": [
["Header-Name"],
["Another-Header"]
],
"hosts": {
"api.example.com": [
{
"paths": ["/endpoint"],
"method": "GET",
"expectedStatus": 200
}
]
}
}Top-Level Fields
hosts
Type: object (required)
Description: Maps hostnames to arrays of test cases.
{
"hosts": {
"api.example.com": [...],
"admin.example.com": [...],
"gateway.example.com": [...]
}
}Key points:
- Keys are hostname values for the
Hostheader - Each hostname has an array of test case objects
- Tests are executed in order within each host
collectionHeaders
Type: array (optional)
Description: Headers that should be present in all tests. Reduces duplication.
{
"collectionHeaders": [
["X-Request-Id"],
["X-API-Version"],
["X-Client-Type"]
]
}Usage: Reference collection headers in test cases using $collectionHeaders:
{
"paths": ["/api/users"],
"expectedRequestHeadersToUpstream": [
["$collectionHeaders"],
["X-Forwarded-For"]
]
}Test Case Object
Each test case in a host array has the following fields:
paths
Type: array (required)
Description: List of URL paths to test with identical assertions.
{
"paths": ["/health", "/status", "/ping"],
"method": "GET",
"expectedStatus": 200
}Key points:
- All paths in the array use the same method and assertions
- Useful for testing multiple endpoints with similar behavior
- Each path is tested independently
method
Type: string (required)
Description: HTTP method for the request.
Supported methods:
GETPOSTPUTDELETEPATCHHEADOPTIONS
{
"paths": ["/api/users"],
"method": "POST",
"expectedStatus": 201
}expectedStatus
Type: integer (required)
Description: Expected HTTP status code.
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200
}Common status codes:
200- OK201- Created204- No Content400- Bad Request401- Unauthorized403- Forbidden404- Not Found500- Internal Server Error502- Bad Gateway503- Service Unavailable
expectedResponseHeaders
Type: array (optional)
Description: Headers that must be present in the response.
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["Content-Type", "application/json"],
["X-API-Version", "v1"],
["Cache-Control"]
]
}Format:
["Header-Name"]- Header must exist (any value)["Header-Name", "expected-value"]- Header must exist with specific value
Validation:
- Header names are case-insensitive
- Header values are case-sensitive
- If only header name is provided, any value is accepted
- If both name and value provided, value must match exactly
expectedRequestHeadersToUpstream
Type: array (optional)
Description: Headers that must be forwarded to the upstream service.
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
["$collectionHeaders"],
["X-Forwarded-For"],
["X-Real-IP"],
["X-Upstream-Target", "backend:5001"]
]
}How it works:
- HTTPTests uses the mock service's echo functionality
- Mock service returns all headers it received
- Test validates these headers were forwarded correctly
- Useful for proxy and gateway testing
Special values:
["$collectionHeaders"]- Expands to all headers fromcollectionHeaders["Header-Name"]- Header must be present (any value)["Header-Name", "value"]- Header must have specific value
additionalRequestHeaders
Type: object (optional)
Description: Extra headers to include in the test request.
{
"paths": ["/api/users"],
"method": "GET",
"additionalRequestHeaders": {
"X-API-Key": "secret-key-12345",
"Authorization": "Bearer token123",
"X-Custom-Header": "custom-value"
},
"expectedStatus": 200
}Use cases:
- Testing authentication (API keys, tokens)
- Testing authorization headers
- Testing custom header handling
- Simulating different client types
Complete Examples
Simple Health Check
{
"hosts": {
"api.example.com": [
{
"paths": ["/health"],
"method": "GET",
"expectedStatus": 200
}
]
}
}Multiple Endpoints with Same Behavior
{
"hosts": {
"api.example.com": [
{
"paths": ["/health", "/status", "/ping", "/ready"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["Content-Type", "application/json"]
]
}
]
}
}REST API Testing
{
"hosts": {
"api.example.com": [
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["Content-Type", "application/json"],
["X-Total-Count"]
]
},
{
"paths": ["/api/users"],
"method": "POST",
"expectedStatus": 201,
"expectedResponseHeaders": [
["Content-Type", "application/json"],
["Location"]
]
},
{
"paths": ["/api/users/123"],
"method": "PUT",
"expectedStatus": 200
},
{
"paths": ["/api/users/123"],
"method": "DELETE",
"expectedStatus": 204
}
]
}
}Proxy Header Forwarding
{
"collectionHeaders": [
["X-Request-Id"],
["X-Trace-Id"]
],
"hosts": {
"api.example.com": [
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
["$collectionHeaders"],
["X-Forwarded-For"],
["X-Real-IP"],
["Host", "api.example.com"],
["X-Forwarded-Proto", "http"]
]
}
]
}
}Upstream Target Validation
{
"hosts": {
"api.example.com": [
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
["X-Upstream-Target", "backend:5001"]
]
},
{
"paths": ["/api/payments"],
"method": "GET",
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
["X-Upstream-Target", "payment-service:8080"]
]
}
]
}
}API Gateway with Authentication
{
"collectionHeaders": [
["X-Request-ID"]
],
"hosts": {
"gateway.example.com": [
{
"paths": ["/public/info"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["X-RateLimit-Limit", "1000"]
]
},
{
"paths": ["/api/users"],
"method": "GET",
"additionalRequestHeaders": {
"X-API-Key": "valid-api-key-12345"
},
"expectedStatus": 200,
"expectedResponseHeaders": [
["X-RateLimit-Limit", "100"],
["X-Auth-Status"]
],
"expectedRequestHeadersToUpstream": [
["$collectionHeaders"],
["X-Auth-Status", "authenticated"],
["X-User-Tier", "standard"]
]
},
{
"paths": ["/admin/settings"],
"method": "GET",
"additionalRequestHeaders": {
"X-API-Key": "admin-key-67890"
},
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
["X-User-Tier", "admin"]
]
}
]
}
}Multiple Hosts
{
"hosts": {
"api.example.com": [
{
"paths": ["/health"],
"method": "GET",
"expectedStatus": 200
}
],
"admin.example.com": [
{
"paths": ["/dashboard"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["Content-Type", "text/html"]
]
}
],
"cdn.example.com": [
{
"paths": ["/static/app.js"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["Content-Type", "application/javascript"],
["Cache-Control", "public, max-age=31536000"]
]
}
]
}
}Validation Rules
HTTPTests validates your test.json file:
Required Fields
Each test case must have:
- ✅
paths(non-empty array) - ✅
method(valid HTTP method) - ✅
expectedStatus(valid status code)
Optional Fields
expectedResponseHeaders(array)expectedRequestHeadersToUpstream(array)additionalRequestHeaders(object)
Common Mistakes
❌ Empty paths array:
{
"paths": [], // ERROR: Must have at least one path
"method": "GET"
}❌ Invalid method:
{
"paths": ["/api/users"],
"method": "INVALID", // ERROR: Not a valid HTTP method
"expectedStatus": 200
}❌ Trailing commas:
{
"paths": ["/health"],
"method": "GET",
"expectedStatus": 200, // ERROR: Trailing comma in JSON
}❌ Missing quotes:
{
"paths": ["/health"],
method: "GET", // ERROR: Key must be quoted
"expectedStatus": 200
}✅ Correct:
{
"paths": ["/health"],
"method": "GET",
"expectedStatus": 200
}Best Practices
1. Use Collection Headers for Common Headers
// Good - DRY principle
{
"collectionHeaders": [
["X-Request-Id"],
["X-Trace-Id"]
],
"hosts": {
"api.example.com": [
{
"paths": ["/users"],
"method": "GET",
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
["$collectionHeaders"]
]
}
]
}
}
// Bad - Repetitive
{
"hosts": {
"api.example.com": [
{
"paths": ["/users"],
"expectedRequestHeadersToUpstream": [
["X-Request-Id"],
["X-Trace-Id"]
]
},
{
"paths": ["/posts"],
"expectedRequestHeadersToUpstream": [
["X-Request-Id"],
["X-Trace-Id"]
]
}
]
}
}2. Group Related Paths
{
"hosts": {
"api.example.com": [
// Health checks
{
"paths": ["/health", "/status", "/ping"],
"method": "GET",
"expectedStatus": 200
},
// User endpoints
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200
},
{
"paths": ["/api/users"],
"method": "POST",
"expectedStatus": 201
}
]
}
}3. Test Critical Headers
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["Content-Type", "application/json"],
["X-API-Version"],
["X-RateLimit-Remaining"],
["Cache-Control"]
]
}4. Validate Upstream Targets
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedRequestHeadersToUpstream": [
// Ensure routing to correct backend
["X-Upstream-Target", "user-service:5001"]
]
}5. Test Different HTTP Methods
{
"hosts": {
"api.example.com": [
{"paths": ["/resource"], "method": "GET", "expectedStatus": 200},
{"paths": ["/resource"], "method": "POST", "expectedStatus": 201},
{"paths": ["/resource"], "method": "PUT", "expectedStatus": 200},
{"paths": ["/resource"], "method": "DELETE", "expectedStatus": 204}
]
}
}Tips and Tricks
Testing CORS Headers
{
"paths": ["/api/users"],
"method": "OPTIONS",
"expectedStatus": 204,
"expectedResponseHeaders": [
["Access-Control-Allow-Origin", "*"],
["Access-Control-Allow-Methods"],
["Access-Control-Allow-Headers"]
]
}Testing Rate Limiting
{
"paths": ["/api/users"],
"method": "GET",
"expectedStatus": 200,
"expectedResponseHeaders": [
["X-RateLimit-Limit"],
["X-RateLimit-Remaining"],
["X-RateLimit-Reset"]
]
}Testing Authentication
{
"hosts": {
"api.example.com": [
{
"paths": ["/api/protected"],
"method": "GET",
"expectedStatus": 401,
"comment": "No auth header = 401"
},
{
"paths": ["/api/protected"],
"method": "GET",
"additionalRequestHeaders": {
"Authorization": "Bearer valid-token"
},
"expectedStatus": 200,
"comment": "Valid auth = 200"
}
]
}
}Note: JSON doesn't support comments, but the structure shows the concept.
Next Steps
- Learn about config.yml for service configuration
- See working examples with real test files
- Understand collection headers in depth
- Explore upstream tracking capabilities