Skip to main content

API REFERENCE

Karate Keywords Reference

Complete reference of all Karate DSL keywords, actions, and the karate object.

On this page:

Feature Structure

Every Karate test file must have a .feature extension and follow this structure.

Feature

The Feature: declaration is required at the top of every feature file:

Gherkin
Feature: User API Tests

Scenario: Get user
Given url 'https://jsonplaceholder.typicode.com'
And path 'users', 1
When method get
Then status 200

Background

Runs before each Scenario in the feature. Use for shared setup:

Gherkin
Feature: User API

Background:
* url 'https://jsonplaceholder.typicode.com'
* def authToken = 'Bearer abc123'

Scenario: Get user
* path 'users', 1
* method get
* status 200

Scenario: Get posts
* path 'posts', 1
* method get
* status 200

Scenario

Defines a single test case:

Gherkin
Feature: User tests

Scenario: Create and verify user
Given url 'https://jsonplaceholder.typicode.com'
And path 'users'
And request { name: 'John', username: 'john' }
When method post
Then status 201
And match response.name == 'John'

Scenario Outline

Data-driven tests with multiple examples. Use <placeholder> syntax or direct variable references:

Gherkin
Feature: Data-driven tests

Scenario Outline: Get users by ID
Given url 'https://jsonplaceholder.typicode.com'
And path 'users', <id>
When method get
Then status 200
And match response.name == '<name>'

Examples:
| id | name |
| 1 | Leanne Graham |
| 2 | Ervin Howell |
| 3 | Clementine Bauch |

Core Keywords

def

Define variables of any type:

* def name = 'John'
* def age = 30
* def active = true
* def user = { name: 'John', age: 30 }
* def items = [1, 2, 3]
* def result = call read('helper.feature')

match

Assert and validate data. The primary assertion keyword:

* match response == { id: 1, name: 'John' }
* match response.id == 1
* match response contains { name: 'John' }
* match response.items == '#[]'
* match each response.users == { id: '#number', name: '#string' }

See Assertions for all match variants.

call

Call another feature file or JavaScript function:

* def result = call read('auth.feature')
* def result = call read('auth.feature') { username: 'john' }
* def token = call read('auth.feature@login')
* def computed = call myFunction

callonce

Call a feature file only once per feature (cached across scenarios):

* def auth = callonce read('auth.feature')
* callonce read('setup.feature')

read

Read files from classpath or filesystem:

* def data = read('data.json')
* def users = read('classpath:data/users.csv')
* def template = read('template.xml')
* def config = read('this:config.json')
PrefixDescription
classpath:From classpath (src/test/resources)
file:Absolute file path
this:Relative to current feature file

get

Extract values using JsonPath or XPath:

* def name = get response.user.name
* def first = get[0] response.users
* def ids = get response..id
* def adults = get users[?(@.age > 18)]

Short-cut forms:

* def name = response.user.name
* def first = response.users[0]

set

Set nested values in JSON or XML:

* set user.name = 'John'
* set user.address.city = 'Boston'
* set items[0].active = true
* set response.items[*].processed = true

Multi-value form:

* set user
| path | value |
| name | 'John' |
| age | 30 |

remove

Remove keys from JSON or nodes from XML:

* remove response.password
* remove response..internal
* remove response.users[0]

replace

Text replacement in strings:

* replace text.'{name}' = 'John'
* replace text.'{id}' = id

Multi-value form:

* replace text
| token | value |
| {name} | John |
| {id} | 123 |

copy

Deep copy a variable (prevents mutation):

* copy user = response.user
* set user.name = 'Modified'
# response.user.name is unchanged

table

Define inline data tables:

* table users
| name | age |
| John | 30 |
| Jane | 25 |
* match users == [{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }]

text

Multi-line text (preserves formatting):

* text query =
"""
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}
"""

doc

Add documentation to HTML reports:

* doc 'This scenario tests the user creation flow'

listen

Wait for async events with timeout (milliseconds):

* listen 5000
* match listenResult == { type: 'notification' }

HTTP Keywords

url

Set the base URL:

* url 'https://jsonplaceholder.typicode.com'
* url baseUrl

path

Append path segments to URL:

* path 'users'
* path 'users', userId
* path 'users', 1, 'posts'

method

Execute HTTP request:

* method get
* method post
* method put
* method patch
* method delete
* method head
* method options

request

Set request body:

* request { name: 'John', email: 'john@test.com' }
* request read('request.json')
* request ''

header / headers

Set request headers:

* header Accept = 'application/json'
* header Authorization = 'Bearer ' + token
* headers { 'Content-Type': 'application/json', 'X-Api-Key': apiKey }

param / params

Set query parameters:

* param page = 1
* param size = 10
* params { page: 1, size: 10, sort: 'name' }

Set cookies:

* cookie session = 'abc123'
* cookies { session: 'abc123', userId: '456' }

form field / form fields

Set form data (application/x-www-form-urlencoded):

* form field username = 'john'
* form field password = 'secret'
* form fields { username: 'john', password: 'secret' }

multipart field / multipart fields

Set multipart form fields:

* multipart field name = 'John'
* multipart field file = { read: 'test.pdf', filename: 'test.pdf' }
* multipart fields { name: 'John', email: 'john@test.com' }

multipart file / multipart files

Upload files:

* multipart file myFile = { read: 'test.pdf', filename: 'test.pdf', contentType: 'application/pdf' }
* multipart files { file1: { read: 'a.pdf' }, file2: { read: 'b.pdf' } }

multipart entity

Set entire multipart body with custom content type:

* multipart entity read('data.json')

soap action

Set SOAP action header and execute POST:

* soap action 'http://tempuri.org/GetUser'

status

Assert response status code:

* status 200
* status 201
* status 404

Response Variables

These are automatically set after each HTTP request.

VariableTypeDescription
responseanyResponse body (auto-parsed as JSON/XML)
responseStatusnumberHTTP status code
responseHeadersobjectResponse headers (values are arrays)
responseCookiesobjectResponse cookies
responseTimenumberResponse time in milliseconds
responseBytesbyte[]Raw response as byte array
responseTypestringResponse content type
requestTimeStampnumberRequest timestamp (epoch ms)
* method get
* match responseStatus == 200
* match responseHeaders['Content-Type'][0] contains 'json'
* assert responseTime < 1000
* def bytes = responseBytes

prevRequest

Inspect the actual HTTP request that was sent:

* method post
* print prevRequest.uri
* print prevRequest.method
* print prevRequest.headers
* print prevRequest.body

Assertions

match ==

Exact equality:

* match response == { id: 1, name: 'John' }
* match response.id == 1

match !=

Not equals:

* match response.status != 'error'
* match response != { error: true }

match contains

Partial match (subset):

* match response contains { name: 'John' }
* match response.items contains { id: 1 }

match !contains

Does not contain:

* match response !contains { error: true }
* match response.roles !contains 'admin'

match contains only

Contains exactly these items (any order):

* match response.items contains only [{ id: 2 }, { id: 1 }]

match contains any

Contains at least one of:

* match response.tags contains any ['urgent', 'high']

match contains deep

Deep partial match (recursive):

* match response contains deep { user: { name: 'John' } }

match contains only deep

Contains exactly these items with deep comparison (any order):

* match response.items contains only deep [{ id: 1, data: { x: 1 } }]

match each

Validate each element in array:

* match each response.users == { id: '#number', name: '#string' }
* match each response.users contains { active: true }

match each contains deep

Each element contains (deep):

* match each response.orders contains deep { items: [{ price: '#number' }] }

match header

Match response header:

* match header Content-Type contains 'json'

assert

Boolean assertions (use for comparisons like >, <):

* assert response.count > 0
* assert response.items.length >= 10
* assert responseTime < 1000

print

Debug output (appears in console and reports):

* print response
* print 'Status:', responseStatus
* print karate.pretty(response)

Type Conversion

json

Convert to JSON:

* json data = '{"name":"John"}'
* json data = xmlResponse

xml

Convert to XML:

* xml data = '<user><name>John</name></user>'
* xml data = jsonResponse

string

Convert to string:

* string jsonText = { name: 'John' }
* match jsonText == '{"name":"John"}'

xmlstring

Convert XML to string:

* xmlstring text = xmlData

bytes

Convert to byte array:

* bytes data = read('file.pdf')

yaml

Parse YAML to JSON:

* yaml data =
"""
name: John
age: 30
"""
* match data == { name: 'John', age: 30 }

csv

Read CSV as JSON array:

* def users = read('users.csv')
* match users[0] == { name: 'John', age: '30' }

Control Flow

if

Conditional execution:

* if (responseStatus == 200) karate.call('success.feature')
* if (env == 'dev') karate.set('baseUrl', devUrl)

eval

Execute JavaScript:

* eval response.items.forEach(x => x.processed = true)
* eval if (condition) karate.set('flag', true)

retry until

Retry request until condition is met:

* configure retry = { count: 10, interval: 1000 }
* Given url 'https://jsonplaceholder.typicode.com'
* And path 'users', 1
* And retry until response.status == 'complete'
* When method get
warning

The retry until expression must be pure JavaScript. Karate match syntax will not work.

Configuration Options

Use configure to set options. Can be done in karate-config.js or feature files.

HTTP Configuration

OptionTypeDefaultDescription
urlstring-Base URL for all requests
sslboolean/JSONfalseEnable SSL/TLS
connectTimeoutnumber30000Connection timeout (ms)
readTimeoutnumber30000Read timeout (ms)
proxystring/JSON-HTTP proxy settings
followRedirectsbooleantrueFollow HTTP redirects
charsetstring'utf-8'Request charset
headersJSON/function-Default headers for all requests
cookiesJSON-Default cookies (null to clear)
localAddressstring-Local network interface
httpRetryEnabledbooleanfalseAuto-retry on connection errors
lowerCaseResponseHeadersbooleanfalseLowercase response header keys
* configure ssl = true
* configure connectTimeout = 60000
* configure headers = { 'X-Api-Key': '#(apiKey)' }
* configure proxy = { uri: 'http://proxy:8080', username: 'user', password: 'pass' }

SSL Configuration

* configure ssl = { keyStore: 'classpath:certs.pfx', keyStorePassword: 'secret', keyStoreType: 'pkcs12' }
* configure ssl = { trustAll: true }
OptionDescription
keyStorePath to client certificate
keyStorePasswordCertificate password
keyStoreTypeFormat (pkcs12, jks)
trustStorePath to trust store
trustStorePasswordTrust store password
trustAllTrust all certificates
algorithmSSL algorithm (TLS, TLSv1.2)

Logging and Reports

OptionTypeDefaultDescription
logPrettyRequestbooleanfalsePretty print requests
logPrettyResponsebooleanfalsePretty print responses
printEnabledbooleantrueEnable print output
reportJSON/booleantrueReport verbosity
logModifierfunction-Mask sensitive data
* configure report = { showLog: true, showAllSteps: false }
* configure logModifier = function(text){ return text.replace(/password=\w+/, 'password=***') }

Retry Configuration

* configure retry = { count: 3, interval: 5000 }

Hooks

OptionDescription
afterScenarioRun after each Scenario
afterScenarioOutlineRun after Scenario Outline completes
afterFeatureRun after Feature completes
* configure afterScenario = function(){ karate.log('Scenario done:', karate.scenario.name) }

Mock Server

OptionDescription
corsEnable CORS (boolean)
responseHeadersDefault response headers

Other Options

OptionTypeDefaultDescription
callSingleCacheJSON{minutes:0}Cache for callSingle
abortedStepsShouldPassbooleanfalseMark aborted steps as passed
abortSuiteOnFailurebooleanfalseStop on first failure
xmlNamespaceAwarebooleanfalseXML namespace handling
matchEachEmptyAllowedbooleanfalseAllow empty arrays in match each
pauseIfNotPerfbooleanfalsePause in non-perf mode
ntlmAuthJSON-NTLM authentication
driverJSON-UI automation driver
driverTargetJSON-Driver target config
imageComparisonJSON-Image comparison options

The karate Object

The karate object provides utility methods and runtime information.

Properties

PropertyDescription
karate.envCurrent environment (karate.env system property)
karate.propertiesAccess Java system properties
karate.osOS info: { type: 'macosx', name: 'Mac OS X' }
karate.featureCurrent feature metadata
karate.scenarioCurrent scenario metadata
karate.scenarioOutlineScenario outline metadata
karate.tagsCurrent scenario tags
karate.tagValuesTag values for @name=value format
karate.prevRequestLast HTTP request details
karate.infoRuntime information
karate.optionsCommand-line options
* print 'Environment:', karate.env
* def port = karate.properties['server.port']
* def isWindows = karate.os.type == 'windows'
* print 'Scenario:', karate.scenario.name

Core Methods

MethodDescription
karate.call(feature, [arg])Call feature file
karate.callSingle(feature, [arg])Call once and cache
karate.read(path)Read file
karate.readAsString(path)Read file as string (no auto-convert)
karate.readAsBytes(path)Read file as byte array
karate.readAsStream(path)Read file as InputStream
karate.write(object, path)Write to file (in target/)
karate.get(name, [default])Get variable value
karate.set(name, value)Set variable value
karate.set(name, path, value)Set nested value
karate.set(object)Set multiple from map
karate.remove(name, path)Remove from JSON/XML
karate.setXml(name, xmlString)Set XML value
* def result = karate.call('helper.feature')
* def config = karate.callSingle('classpath:setup.feature')
* def foo = karate.get('foo', 'default')
* karate.set('myVar', 123)

JSON/XML Methods

MethodDescription
karate.jsonPath(json, expr)Evaluate JsonPath
karate.xmlPath(xml, expr)Evaluate XPath
karate.pretty(json)Pretty print JSON
karate.prettyXml(xml)Pretty print XML
karate.fromString(string)Auto-detect and parse JSON/XML
karate.toJson(object, [removeNulls])Convert to JSON
karate.lowerCase(object)Lowercase all keys/values
* def names = karate.jsonPath(response, '$.users[*].name')
* def title = karate.xmlPath(doc, '//book/title')
* print karate.pretty(response)

Collection Methods

MethodDescription
karate.map(list, fn)Transform each element
karate.filter(list, fn)Filter elements
karate.forEach(list, fn)Iterate with side effects
karate.filterKeys(map, keys)Extract subset of keys
karate.merge(...maps)Merge objects
karate.append(...items)Combine arrays/objects
karate.appendTo(name, ...items)Append to existing array
karate.mapWithKey(list, key)Transform primitives to objects
karate.sort(list, [fn])Sort array
karate.distinct(list)Remove duplicates
karate.repeat(count, fn)Execute n times
karate.range(start, end, [step])Generate number range
karate.keysOf(object)Get object keys
karate.valuesOf(object)Get object values
karate.sizeOf(object)Get size/length
karate.typeOf(value)Get type name
* def ids = karate.map(response.users, x => x.id)
* def active = karate.filter(response.users, x => x.active)
* def merged = karate.merge(defaults, overrides)
* def items = karate.repeat(5, i => ({ id: i }))

String Methods

MethodDescription
karate.extract(text, regex, group)Extract regex match
karate.extractAll(text, regex, [group])Extract all matches
karate.urlEncode(string)URL encode
karate.urlDecode(string)URL decode
* def id = karate.extract(text, 'id=(\\d+)', 1)
* def numbers = karate.extractAll(text, '\\d+')
* def encoded = karate.urlEncode('hello world')

Random/Utility Methods

MethodDescription
karate.uuid()Generate UUID
karate.random([max])Random number (0 to max-1)
karate.now()Current timestamp (epoch ms)
karate.match(actual, expected)Fuzzy match (returns { pass, message })
* def id = karate.uuid()
* def num = karate.random(100)
* def time = karate.now()

Type Conversion Methods

MethodDescription
karate.toBean(json, className)JSON to Java object
karate.toJava(function)JS function to Java
karate.toJavaFile(path)Get java.io.File
karate.toMap(object)Convert to Java Map
karate.toCsv(list)JSON array to CSV string
karate.toAbsolutePath(path)Get absolute file path

Logging and Output

MethodDescription
karate.log(...args)Log message
karate.logger.debug(...args)Debug level log
karate.embed(bytes, mimeType)Embed in HTML report
karate.render(template)Render HTML template
karate.doc(html)Render and embed in report
* karate.log('Processing:', response.id)
* karate.embed(screenshot, 'image/png')

Flow Control

MethodDescription
karate.abort()Exit scenario (not failed)
karate.fail(message)Fail with message
karate.stop(port)Pause for debugging
karate.pause(ms)Sleep (only in perf mode by default)
* if (condition) karate.abort()
* if (!valid) karate.fail('Validation failed: ' + message)

Async Methods

MethodDescription
karate.signal(result)Trigger async event
karate.listen(timeout)Wait for signal (keyword)
karate.waitForHttp(url)Wait for HTTP endpoint
karate.waitForPort(host, port)Wait for TCP port
karate.webSocket(url, [handler], [options])WebSocket connection
karate.webSocketBinary(url, ...)Binary WebSocket
* def socket = karate.webSocket(wsUrl, handler)
* socket.send('hello')
* listen 5000
* match listenResult == 'response'

OS/Exec Methods

MethodDescription
karate.exec(command)Execute OS command (blocking)
karate.fork(command)Execute OS command (non-blocking)
* def output = karate.exec('ls -la')
* def proc = karate.fork('npm start')

Setup Methods

MethodDescription
karate.setup([name])Call @setup scenario
karate.setupOnce([name])Call @setup once (cached)
karate.configure(key, value)Set configuration
karate.start(mockFeature)Start mock server
karate.http(url)HTTP request builder
karate.target(object)UI target lifecycle
karate.compareImage(baseline, latest, [options])Image comparison

Magic Variables

Special variables available in certain contexts.

Call Arguments

Available in called features:

VariableDescription
__argSingle argument passed to call (null if none)
__loopLoop iteration index (-1 if not in loop)
# In called feature:
* def data = __arg
* print 'Iteration:', __loop

Scenario Outline Variables

Available in Scenario Outline Examples:

VariableDescription
__rowEntire row as JSON object
__numRow index (0-based)
Feature: Outline magic variables

Scenario Outline: Test with row data
* print 'Row index:', __num
* print 'Full row:', __row
* match __row.name == name

Examples:
| name | age |
| John | 30 |
| Jane | 25 |

Async Variables

VariableDescription
listenResultResult from karate.signal() after listen
* listen 5000
* match listenResult == { type: 'done' }

Mock Server Keywords

Used in mock feature files. See Test Doubles for details.

Request Matching

FunctionDescription
pathMatches(pattern)Match URL path with placeholders
paramExists(name)Check query parameter exists
paramValue(name)Get query parameter value
methodIs(method)Match HTTP method
typeContains(text)Match Content-Type
acceptContains(text)Match Accept header
headerContains(name, value)Match header value
bodyPath(path)Extract from request body
Scenario: pathMatches('/users/{id}') && methodIs('get')
* def response = { id: pathParams.id, name: 'John' }

Request Variables

VariableDescription
requestRequest body
requestBytesRequest as byte array
requestPathRequest path
requestUrlBaseBase URL
requestUriFull URI with query
requestMethodHTTP method
requestHeadersRequest headers
requestParamsQuery parameters
requestPartsMultipart parts
pathParamsPath parameters from pathMatches

Tags

Special tags that control test behavior.

@ignore

Skip scenario at runtime:

@ignore
Scenario: This test is disabled

@setup

Mark as setup scenario (called via karate.setup()):

@setup
Scenario: Initialize test data
* def users = [{id: 1}, {id: 2}]

@parallel=false

Disable parallel execution:

@parallel=false
Scenario: Must run sequentially

@report=false

Hide from HTML reports:

@report=false
Scenario: Internal helper

@env

Run only when karate.env matches:

@env=dev
Scenario: Runs only in dev environment

@env=dev,staging
Scenario: Runs in dev or staging

@envnot

Run when karate.env does NOT match:

@envnot=prod
Scenario: Never runs in production

@timeout

Set custom timeout for scenario (in development):

@timeout=60000
Scenario: Long running test

See Also