Skip to main content

ASSERTIONS

Fuzzy Matching

Validate response structure and types without requiring exact values. Use markers like #string, #number, and #ignore to handle dynamic data such as timestamps, UUIDs, and auto-generated IDs.

On this page:

Validation Markers

Use markers to validate types without asserting exact values:

MarkerDescription
#ignoreSkip validation for this field
#nullValue must be null (key must exist)
#notnullValue must not be null
#presentKey must exist (any value including null)
#notpresentKey must not exist
#stringMust be a string
#numberMust be a number
#booleanMust be true or false
#arrayMust be a JSON array
#objectMust be a JSON object
#uuidMust be a valid UUID string
#regex STRMust match the regular expression
#? EXPRCustom JavaScript validation

Ignore Dynamic Fields

Use #ignore to skip validation for fields with unpredictable values:

Gherkin
Feature: Ignore dynamic fields

Scenario: Validate response with dynamic ID
Given url 'https://jsonplaceholder.typicode.com'
And path 'posts'
And request { title: 'Test Post', body: 'Content', userId: 1 }
When method post
Then status 201
And match response == { id: '#ignore', title: 'Test Post', body: 'Content', userId: 1 }

Type Validation

Validate field types without checking exact values:

Gherkin
Feature: Type validation

Scenario: Validate field types
Given url 'https://jsonplaceholder.typicode.com'
And path 'users', 1
When method get
Then status 200
And match response ==
"""
{
id: '#number',
name: '#string',
username: '#string',
email: '#string',
address: '#object',
phone: '#string',
website: '#string',
company: '#object'
}
"""

Null vs Not Present

Karate distinguishes between a key with a null value and a missing key:

Gherkin
Feature: Null vs not present

Scenario: Understand the difference
* def withNull = { id: 1, value: null }
* def withoutKey = { id: 1 }

# Key exists with null value
* match withNull == { id: 1, value: '#null' }
* match withNull == { id: 1, value: '#present' }

# Key doesn't exist at all
* match withoutKey == { id: 1, value: '#notpresent' }
* match withoutKey.value == '#notpresent'
tip

Use #null when a key must exist with a null value. Use #notpresent when the key should be completely absent from the response.

Optional Fields

Prefix any marker with ## to make a field optional (can be missing or match the type):

Gherkin
Feature: Optional fields

Scenario: Handle optional fields
* def user = { name: 'John', age: 30 }

# bio is missing but passes because ## makes it optional
* match user == { name: '#string', age: '#number', bio: '##string' }

# Also works when field is present
* def userWithBio = { name: 'John', age: 30, bio: 'Developer' }
* match userWithBio == { name: '#string', age: '#number', bio: '##string' }

The ## prefix means "this field can be missing entirely, or if present, must match the type":

Gherkin
Feature: Optional patterns

Scenario: Optional null handling
* def data = { id: 1 }

# All pass - optional key is missing
* match data == { id: '#number', extra: '##string' }
* match data == { id: '#number', extra: '##null' }
* match data == { id: '#number', extra: '##object' }

Regex Matching

Use #regex followed by a pattern to validate string formats:

Gherkin
Feature: Regex matching

Scenario: Validate string patterns
Given url 'https://jsonplaceholder.typicode.com'
And path 'users', 1
When method get
Then status 200
# Email pattern validation
* match response.email == '#regex .+@.+\\..+'
# Website pattern
* match response.website == '#regex [a-z]+\\.[a-z]+'
Regex Escaping

Use double backslashes for special regex characters: #regex a\\.dot matches a.dot

Self-Validation Expressions

Use #? EXPR for custom validation where _ represents the field value:

Gherkin
Feature: Custom validation

Scenario: Validate with expressions
Given url 'https://jsonplaceholder.typicode.com'
And path 'posts'
When method get
Then status 200
# Validate array has 100 items
* match response == '#[100]'
# Validate each item has positive IDs
* match each response == { userId: '#? _ > 0', id: '#? _ > 0', title: '#string', body: '#string' }

Common expressions:

  • #? _ > 0 - Value greater than zero
  • #? _.length > 0 - Non-empty string or array
  • #? _ != null - Same as #notnull

Contains Shortcuts

Use shortcut symbols within embedded expressions for inline subset matching:

SymbolEquivalent
^contains
^^contains only
^*contains any
^+contains deep
!^not contains
Gherkin
Feature: Contains shortcuts

Scenario: Use contains in embedded expressions
* def requiredFields = { id: '#number', title: '#string' }

Given url 'https://jsonplaceholder.typicode.com'
And path 'posts', 1
When method get
Then status 200
# Response contains at minimum these fields
* match response == '#(^requiredFields)'

For validating arrays:

Gherkin
Feature: Array contains shortcuts

Scenario: Validate array membership
* def data = { tags: ['api', 'test', 'karate'] }

# Contains any of these
* match data.tags == '#(^*["api", "other"])'
# Contains all (any order)
* match data.tags == '#(^^["karate", "api", "test"])'

Combining Markers

Combine fuzzy matching with exact values in the same assertion:

Gherkin
Feature: Combined validation

Scenario: Mix exact and fuzzy matching
Given url 'https://jsonplaceholder.typicode.com'
And path 'posts', 1
When method get
Then status 200
And match response ==
"""
{
userId: 1,
id: 1,
title: '#string',
body: '#string'
}
"""

XML Fuzzy Matching

Fuzzy markers work in XML responses too:

Gherkin
Feature: XML fuzzy matching

Scenario: Validate XML with fuzzy markers
Given url 'https://httpbin.org'
And path 'xml'
When method get
Then status 200
And match response ==
"""
<slideshow title="#string" date="#ignore" author="#string">
<slide type="#string">
<title>#string</title>
</slide>
#ignore
</slideshow>
"""

Next Steps