๐Ÿฅ‹ KarateBDD: Understanding `match` vs `assert`

Himanshu PandeyHimanshu Pandey
5 min read

In API test automation, match and assert are two of the most powerful features of KarateBDD. While both validate data, they do so in fundamentally different ways.

In this guide, you'll:

  • Understand their differences

  • See real-world usage in component, integration, and E2E testing

  • Practice with 3 levels of hands-on exercises


๐Ÿ“˜ Table of Contents

  1. What is match in Karate?

  2. What is assert in Karate?

  3. Key Differences Between match and assert

  4. Real-World API Testing Use Cases

  5. Practice Exercises (Beginner to Advanced)

  6. Conclusion


1๏ธโƒฃ What is match in Karate?

match is used to compare actual vs expected data โ€” especially JSON or XML structures.
It returns pass if the comparison succeeds and fail otherwise.

โœ… Simple Examples

* def response = { name: 'Alice', age: 30 }
* match response.name == 'Alice'  # โœ… Pass: exact match
* match response.name == 'Bob'    # โŒ Fail: value mismatch
* match response == { name: 'Alice', age: 30 }  # โœ… Pass: full object match
* match response == { name: 'Alice' }  # โŒ Fail: partial match is not allowed with `==`

๐Ÿ” match Variants

  • contains โ€“ Partial match allowed
* match response contains { name: 'Alice' }  # โœ… Pass
* match response contains { name: 'Bob' }    # โŒ Fail
  • contains only โ€“ Must contain exactly these values (order doesn't matter)
* def roles = ['admin', 'editor']
* match roles contains only ['editor', 'admin']  # โœ… Pass
* match roles contains only ['admin']            # โŒ Fail
  • contains any โ€“ At least one value must match
* def tags = ['karate', 'api', 'testing']
* match tags contains any ['dev', 'karate']  # โœ… Pass
* match tags contains any ['qa', 'ops']      # โŒ Fail
  • !contains โ€“ Asserts absence of value
* def roles = ['user', 'guest']
* match roles !contains 'admin'  # โœ… Pass: 'admin' not present
* match roles !contains 'guest'  # โŒ Fail: 'guest' is present

2๏ธโƒฃ What is assert in Karate?

assert is used for boolean condition validation.
It evaluates the condition and returns pass if true, otherwise fail.

โœ… Simple Examples

* def age = 25
* assert age > 18  # โœ… Pass
* assert age < 10  # โŒ Fail

๐Ÿง  More Use Cases

* def price = 150
* assert price >= 100 && price <= 200  # โœ… Pass

* def user = { name: 'Lannister' }
* assert typeof user.name == 'string'  # โœ… Pass

* def name = 'karate'
* assert name.length > 3       # โœ… Pass
* assert name.startsWith('k')  # โœ… Pass

๐Ÿ”„ Key Differences

Featurematchassert
PurposeData structure comparisonBoolean condition check
Best ForJSON/XML/API response validationLogical rules, numeric/string checks
OutputDetailed diffPass/fail with message
StyleKarate BDD DSLJavaScript-style syntax

๐ŸŒ Real-World API Testing Use Cases

๐Ÿงฉ Component Test (Microservice level)

* def response = call read('get-user.feature')
* match response == { id: '#number', name: '#string' }  # โœ… Validate structure
* assert response.id > 0                                # โœ… Check value rule

๐Ÿ”— Integration Test (Multiple APIs)

* def user = call read('get-user.feature')
* def orders = call read('get-orders.feature') { userId: user.id }

* match orders contains { userId: user.id }  # โœ… Data relationship
* assert orders.length > 0                   # โœ… Business expectation

๐Ÿš€ End-to-End Test (Full business flow)

* def user = call read('register-user.feature')
* def order = call read('create-order.feature') { userId: user.userId }

* match order contains { status: 'confirmed', userId: user.userId }  # โœ… Flow integrity
* assert order.totalAmount > 0                                       # โœ… Rule enforcement

๐Ÿงช Practice Exercises

๐ŸŸข Level 1 JSON Response

* def response = {
  "name": "Bob",
  "age": 28,
  "active": true
}

๐ŸŸข Level 1: Practice Assertions

#TaskAnswer
1Match a string valuematch response.name == 'Bob'
2Assert number is > 10assert response.age > 10
3Match full objectmatch response == { name: 'Bob', age: 28, active: true }
4Match with containsmatch response contains { active: true }
5Assert a boolean is trueassert response.active == true

๐ŸŸก Level 2 JSON Response

* def response = {
  "roles": ["admin", "editor"],
  "email": "test@gmail.com",
  "profile": {
    "name": "Alice",
    "country": null
  }
}

๐ŸŸก Level 2: Practice Assertions

#TaskAnswer
1Match role list with contains onlymatch response.roles contains only ['admin', 'editor']
2Assert email ends with "@gmail.com"assert response.email.endsWith('@gmail.com')
3Match nested JSON with optional keymatch response.profile contains { country: #null }
4Assert exclusion with !containsmatch response.roles !contains 'banned'
5Combine multiple assertsassert response.email != null && response.roles.length == 2

๐Ÿ”ด Level 3 JSON Response

* def response = [
  { "id": 1, "name": "Item1", "quantity": 50 },
  { "id": 2, "name": "Item2", "quantity": 75 },
  { "id": 3, "name": "Item3", "quantity": 25 }
]

๐Ÿ”ด Level 3: Practice Assertions

#TaskAnswer
1Match each array object structurematch each response == { id: '#number', name: '#string', quantity: '#number' }
2Assert unique IDsassert karate.distinct(response, x => x.id).length == response.length
3Match using regexmatch response[0].name == '#regex ^Item\\d$'
4Assert total quantity > 100assert response[0].quantity + response[1].quantity + response[2].quantity > 100
5Validate chained object integrityassert response[0].id == 1 && response[1].id == 2 && response[2].id == 3

โœ… Conclusion

  • Use match for validating structures and values.

  • Use assert for logic, math, conditions, and expressions.

  • Together, they build expressive, testable, and maintainable API checks.

0
Subscribe to my newsletter

Read articles from Himanshu Pandey directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Himanshu Pandey
Himanshu Pandey