HTTP RESPONSES
Response Validation
Validate API responses using built-in match operations and schema validation markers—no custom assertion libraries or external dependencies required.
Benefits of Response Validation
- Built-in type checking: Validate data types with fuzzy matchers like
#number
,#string
,#array
,#object
- Flexible matching: Choose exact match, partial match, or schema-based validation
- Cross-format support: JSON, XML, and text responses with unified syntax
Simple Response Validation
Validate JSON responses using exact match operations:
Feature: Basic JSON validation
Scenario: Match response fields
Given url baseUrl
And path 'users', 123
When method get
Then status 200
And match response.id == 123
And match response.name == 'John Doe'
And match response.active == true
Match entire response objects for exact validation:
Feature: Exact object matching
Scenario: Validate complete response structure
Given url baseUrl
And path 'users', 123
When method get
Then status 200
And match response == { id: 123, name: 'John Doe', active: true }
Schema Validation
Use type markers to validate response structure without hardcoding values:
Feature: Type-based validation
Scenario: Validate with type markers
Given url baseUrl
And path 'users', 123
When method get
Then status 200
And match response == {
id: '#number',
name: '#string',
email: '#regex .+@.+',
active: '#boolean',
created: '#string'
}
Advanced Validation Markers
Combine type markers with custom validation expressions and optional fields:
Feature: Advanced schema validation
Scenario: Complex validation markers
Given url baseUrl
And path 'api/user-profile'
When method get
Then status 200
And match response == {
id: '#uuid',
score: '#number? _ > 0',
status: '#regex (active|inactive)',
tags: '#[3] #string',
optionalField: '##string',
ignored: '#ignore',
requiredField: '#present'
}
- Use
#
prefix for type markers:#number
,#string
,#array
,#object
- Use
##
prefix for optional fields that may be null or absent - Combine markers with validation:
#number? _ > 0
validates positive numbers - Use
#ignore
to skip validation for specific fields
Array Validation
Validate array size and content with flexible matching:
Feature: Array validation
Scenario: Array size and structure
Given url baseUrl
And path 'users'
When method get
Then status 200
And match response.users == '#[10]'
And match response.users == '#[_ > 5]'
And match each response.users == { id: '#number', name: '#string', active: '#boolean' }
Validate nested arrays and cross-field validation:
Feature: Complex array validation
Scenario: Nested array validation
Given url baseUrl
And path 'api/orders'
When method get
Then status 200
And match each response.orders contains deep {
items: [{ product: '#string', price: '#number' }]
}
And match each response.orders contains {
total: '#? _ > 0'
}
XML Response Validation
Validate XML responses using XPath expressions:
Feature: XML validation
Scenario: XPath validation
Given url baseUrl
And path 'soap/users'
And request <getUserRequest><id>123</id></getUserRequest>
When soap action 'GetUser'
Then status 200
And match response/user/id == '123'
And match response/user/name == 'John Doe'
And match response == <user><id>123</id><name>John Doe</name></user>
Contains Operations
Use contains for order-independent and partial matching:
Feature: Contains validation
Scenario: Partial matching
Given url baseUrl
And path 'api/search'
And param query = 'laptop'
When method get
Then status 200
And match response.results contains { id: 123, name: 'Gaming Laptop' }
And match response.categoryIds contains [1, 3, 5]
And match response !contains { error: '#notnull' }
Advanced Contains Operations
Feature: Advanced contains operations
Scenario: Contains only and any
Given url baseUrl
And path 'api/products'
When method get
Then status 200
And match response.featured contains only [
{ id: 1, name: 'Product A' },
{ id: 2, name: 'Product B' }
]
And match response.categories contains any ['electronics', 'books', 'clothing']
And match response.products contains deep {
metadata: { tags: ['popular'] }
}
Self-Validation Expressions
Use #?
expressions for custom validation logic and cross-field validation:
Feature: Self-validation expressions
Scenario: Custom validation logic
Given url baseUrl
And path 'api/financial-data'
When method get
Then status 200
And match response == {
temperature: {
celsius: '#number',
fahrenheit: '#? _ == $.celsius * 1.8 + 32'
},
date: {
month: '#number? _ > 0 && _ <= 12',
day: '#number? _ > 0 && _ <= 31',
year: '#number? _ > 2020'
},
price: '#number? _ > 0',
email: '#string? _.includes("@")'
}
Define reusable validation functions for complex scenarios:
Feature: Reusable validation functions
Scenario: Custom validators
* def isValidEmail = function(email) { return email.includes('@') && email.includes('.') }
* def isValidPrice = function(price) { return price > 0 && price < 10000 }
Given url baseUrl
And path 'api/user-profile'
When method get
Then status 200
And match response == {
email: '#? isValidEmail(_)',
subscriptionPrice: '#? isValidPrice(_)',
registrationDate: '#? new Date(_).getTime() > 0'
}
File-Based Validation
Compare responses against expected files for regression testing:
Feature: File-based validation
Scenario: Compare to expected response
Given url baseUrl
And path 'api/users', 123
When method get
Then status 200
And match response == read('expected-user-123.json')
And match response.profile == read('expected-user-profile.json')
Use file-based schemas for consistent validation:
Feature: Schema file validation
Scenario: Validate with schema file
Given url baseUrl
And path 'api/products'
When method get
Then status 200
* def productSchema = read('product-schema.json')
And match each response.products == productSchema
Conditional Validation
Apply different validation rules based on environment or context:
Feature: Conditional validation
Scenario: Environment-specific validation
* def env = karate.env || 'dev'
Given url baseUrl
And path 'api/config'
When method get
Then status 200
* if (env == 'prod')
"""
* match response.debugMode == false
* match response.logLevel == 'WARN'
* match response.features contains only ['core', 'stable']
"""
* if (env == 'dev')
"""
* match response.debugMode == true
* match response.logLevel == 'DEBUG'
* match response.features contains 'experimental'
"""
Error Response Validation
Validate error responses with specific structure and field checks:
Feature: Error response validation
Scenario: Validate error responses
Given url baseUrl
And path 'users', 99999
When method get
Then status 404
And match response == {
error: {
code: 'USER_NOT_FOUND',
message: '#string',
details: '##object'
},
timestamp: '#string',
path: '/users/99999'
}
Scenario: Validation error handling
Given url baseUrl
And path 'users'
And request { name: '', email: 'invalid-email' }
When method post
Then status 400
And match response == {
error: 'VALIDATION_ERROR',
message: '#string',
fields: '#[] { field: "#string", message: "#string" }'
}
And match response.fields[*].field contains ['name', 'email']
- Prefer
match
overassert
for better error messages showing expected vs actual - Use
contains
for order-independent array validation - Use
##
prefix for optional fields to handle null or absent values gracefully - JSON keys and string values are case-sensitive
Next Steps
Master response validation and continue with:
- Monitor API performance: Response Time
- Handle response data: Response Handling
- Learn advanced matching: Match Keyword