Q2 of 40 · Karate

Explain how Karate's `* def` and `* match` work in a scenario.

KarateMidkaratekarate-dslapi-testingbddassertions

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 }

    # Containsjust check specific fields exist with correct values
    * match response contains { name: 'Alice' }

    # match eachassert every item in an array matches a pattern
    * def related = response.relatedUsers
    * match each related == { id: '#number', name: '#string' }

// WHAT INTERVIEWERS LOOK FOR

Correct explanation of def as assignment and match as assertion, awareness of match contains vs exact match, and the # wildcard syntax for type checking. Bonus: knowing that def in Background scopes across all scenarios, and that match each applies to every array element.

// COMMON PITFALL

Treating match like Java assertEquals() — just checking one exact value. The power of match is the contains, each, and wildcard patterns. Candidates who haven't written real Karate scenarios often miss the # notation entirely.