Q2 of 40 · Karate
Explain how Karate's `* def` and `* match` work in a scenario.
Short answer
Short answer: `* def` assigns a value to a named variable in the current scenario scope; `* match` asserts equality or structure. Together they are Karate's two primary building blocks: def captures values from responses or fixtures, match verifies them — with built-in support for JSON wildcards and type-check patterns.
Detail
* def assigns a value. The value can be a literal, a JSON object, a response body reference, a JavaScript expression, or a JsonPath expression:
* def userId = 42
* def expectedUser = { id: 42, name: "Alice", active: true }
* def token = response.access_token
* def names = get[*] response.users[*].name
Variables defined with def are in scope for the rest of the scenario. Defined in a Background block, they're available across all scenarios in the feature file.
* match asserts equality or structural matching. It understands:
- Exact match:
* match response == { id: 1, name: "Alice" }— response must be exactly this - Contains:
* match response contains { id: 1 }— response has at least these fields - Each:
* match each response.users == { id: '#number', name: '#string' }— every element matches - Wildcards: the
#prefix means type-check —#number,#string,#boolean,#present,#notpresent,#null,#regex ...
The # syntax is Karate's lightweight schema validation shorthand — you get structural type-checking without writing a separate JSON Schema file. * match each is particularly powerful: it applies the pattern assertion to every element of an array in a single step.
// EXAMPLE
user-api.feature
Feature: User API
Background:
* url 'https://api.example.com'
* def authHeader = { Authorization: 'Bearer test-token' }
Scenario: Create and retrieve a user
# POST — create
Given path '/users'
And headers authHeader
And request { name: 'Alice', email: 'alice@example.com' }
When method POST
Then status 201
# Capture the new user's id with def
* def createdId = response.id
# GET — verify
Given path '/users/' + createdId
And headers authHeader
When method GET
Then status 200
# Exact match with type wildcards
* match response == { id: '#number', name: 'Alice', email: 'alice@example.com', active: true }
# Contains — just check specific fields exist with correct values
* match response contains { name: 'Alice' }
# match each — assert every item in an array matches a pattern
* def related = response.relatedUsers
* match each related == { id: '#number', name: '#string' }