ADVANCED
Karate Object API
The karate object is a runtime utility available in JavaScript functions, Karate expressions, and karate-config.js. It provides methods for test control, data manipulation, HTTP access, and system integration.
On this page:
- Variables and State -- copy, eval, get, remove, set
- Data Transforms -- append, appendTo, distinct, extract, extractAll, filter, filterKeys, forEach, fromJson, fromString, jsonPath, keysOf, lowerCase, map, mapWithKey, merge, range, repeat, sizeOf, sort, valuesOf, xmlPath
- Calling Features -- call, callonce, callSingle
- HTTP -- http, prevRequest, proceed, waitForHttp, waitForPort
- Assertions -- expect, match
- File I/O -- read, readAsBytes, readAsStream, readAsString, toAbsolutePath, write
- Config and Environment -- config, configure, env, feature, info, os, properties, scenario, scenarioOutline, tagValues, tags
- Flow Control -- abort, fail, pause, setup, setupOnce, stop
- Process Execution -- exec, fork
- Async and Events -- channel, signal, start
- Test Data and Utilities -- doc, embed, faker.*, log, pretty, prettyXml, render, toBean, toBytes, toCsv, toJava, toJson, toString, typeOf, urlDecode, urlEncode, uuid
Variables and State
Read and write variables dynamically, especially useful in JavaScript functions and conditional logic.
karate.copy(name)
Deep-copy a variable to prevent mutation of the original. This is exposed as the copy keyword in Gherkin, not as a karate.* function call.
* def original = { name: 'John', scores: [85, 90] }
* copy clone = original
* set clone.name = 'Jane'
* match original.name == 'John'
karate.eval(expression)
Evaluate a string as a JavaScript expression at runtime. Useful when the expression itself is dynamic.
* def field = 'name'
* def result = karate.eval("response." + field)
karate.get(name, [default])
Get a variable by name or JsonPath expression. Returns null (or the optional default) if not found. Supports $variable.path syntax for JsonPath lookups.
* def timeout = karate.get('config.timeout', 3000)
* def first = karate.get('$response.users[0]')
karate.remove(name, path)
Remove a key from a JSON object or a node from XML at the given path.
* def payload = { a: 1, b: 2, secret: 'x' }
* karate.remove('payload', 'secret')
* match payload == { a: 1, b: 2 }
karate.set(name, value) | karate.set(name, path, value)
Set a variable by name, or set a value at a JsonPath/XPath within an existing variable. The two-argument form sets the variable directly; the three-argument form navigates into the variable.
* karate.set('token', 'abc-123')
* def payload = { userId: 1 }
* karate.set('payload', '$.title', 'Hello')
* match payload == { userId: 1, title: 'Hello' }
Data Transforms
Transform, filter, and reshape arrays and objects using functional operations.
karate.append(...items)
Create an array by concatenating items. Each argument that is itself an array is flattened into the result.
* def result = karate.append([1, 2], [3, 4], 5)
* match result == [1, 2, 3, 4, 5]
karate.appendTo(name, ...items)
Append items to an existing array variable in place. The first argument is the variable name as a string.
* def list = [1, 2]
* karate.appendTo('list', 3, 4)
* match list == [1, 2, 3, 4]
karate.distinct(list)
Return unique items from an array of strings or numbers.
* def unique = karate.distinct([1, 2, 2, 3, 1])
* match unique == [1, 2, 3]
karate.extract(text, regex, group)
Extract a single match from text using a regex. The group index follows Java regex capture-group rules.
* def html = '<div class="price">$49.99</div>'
* def price = karate.extract(html, '\\$([0-9.]+)', 1)
* match price == '49.99'
karate.extractAll(text, regex, group)
Extract all matches from text as an array.
* def text = 'a1 b2 c3'
* def nums = karate.extractAll(text, '[a-z]([0-9])', 1)
* match nums == ['1', '2', '3']
karate.filter(list, predicate)
Filter an array. The predicate receives (item, index) and returns a boolean.
* def nums = [1, 2, 3, 4, 5]
* def even = karate.filter(nums, x => x % 2 == 0)
* match even == [2, 4]
karate.filterKeys(map, keys)
Extract a key-value subset from a map. Keys can be an array of strings or another map (only its keys are used).
* def full = { a: 1, b: 2, c: 3 }
* def subset = karate.filterKeys(full, ['a', 'c'])
* match subset == { a: 1, c: 3 }
karate.forEach(list, function)
Iterate an array or object. For arrays the function receives (item, index); for objects it receives (key, value, index). Returns nothing -- use for side effects.
* def names = []
* def users = [{ name: 'Al' }, { name: 'Bo' }]
* karate.forEach(users, x => names.push(x.name))
* match names == ['Al', 'Bo']
karate.fromJson(string)
Parse a JSON string into a Karate object (map or list).
* def raw = '{"a":1}'
* def obj = karate.fromJson(raw)
* match obj == { a: 1 }
karate.fromString(string)
Convert a string to JSON or XML based on its content. Useful when you receive data as a raw string and need it parsed.
* def data = karate.fromString('{"id":1}')
* match karate.typeOf(data) == 'map'
karate.jsonPath(json, expression)
Evaluate a JsonPath expression against a JSON object. Useful for building dynamic filter expressions in JavaScript.
* def users = [{ name: 'Al', age: 30 }, { name: 'Bo', age: 20 }]
* def young = karate.jsonPath(users, "$[?(@.age < 25)]")
* match young[0].name == 'Bo'
karate.keysOf(object)
Return the keys of a map-like object as an array.
* def keys = karate.keysOf({ a: 1, b: 2 })
* match keys == ['a', 'b']
karate.lowerCase(object)
Recursively convert all string keys and values to lowercase.
* def result = karate.lowerCase({ Name: 'JOHN' })
* match result == { name: 'john' }
karate.map(list, function)
Transform each element in an array. The function receives (item, index) and returns the new value.
* def names = karate.map([{ n: 'Al' }, { n: 'Bo' }], x => x.n)
* match names == ['Al', 'Bo']
karate.mapWithKey(list, key)
Convert an array of primitives into an array of objects, each with the given key.
* def result = karate.mapWithKey(['a', 'b'], 'letter')
* match result == [{ letter: 'a' }, { letter: 'b' }]
karate.merge(...maps)
Merge multiple JSON objects into one. Later objects override earlier keys.
* def defaults = { timeout: 5000, retries: 3 }
* def overrides = { timeout: 10000 }
* def config = karate.merge(defaults, overrides)
* match config == { timeout: 10000, retries: 3 }
karate.range(start, end, [interval])
Return an array of integers from start to end (inclusive). Default interval is 1.
* def nums = karate.range(1, 5)
* match nums == [1, 2, 3, 4, 5]
* def odds = karate.range(1, 9, 2)
* match odds == [1, 3, 5, 7, 9]
karate.repeat(count, function)
Build an array by executing a function count times. The function receives the current index.
* def ids = karate.repeat(3, i => ({ id: i + 1 }))
* match ids == [{ id: 1 }, { id: 2 }, { id: 3 }]
karate.sizeOf(object)
Return the size of an array (length) or object (number of keys).
* match karate.sizeOf([1, 2, 3]) == 3
* match karate.sizeOf({ a: 1, b: 2 }) == 2
karate.sort(list, [function])
Sort an array. The optional function receives an item and returns the sort value. Without a function, natural ordering is used.
* def items = [{ p: 3 }, { p: 1 }, { p: 2 }]
* def sorted = karate.sort(items, x => x.p)
* match sorted[0].p == 1
karate.valuesOf(object)
Return only the values of a map-like object as an array.
* def vals = karate.valuesOf({ a: 1, b: 2 })
* match vals == [1, 2]
karate.xmlPath(xml, expression)
Evaluate an XPath expression against an XML document. Useful for dynamic XPath expressions built at runtime.
* def xml = <root><item id="1"/><item id="2"/></root>
* def id = karate.xmlPath(xml, '/root/item[1]/@id')
* match id == '1'
Use karate.filter(), karate.map(), and karate.forEach() instead of JavaScript for loops. Use karate.repeat() when you need to execute something a fixed number of times.
Calling Features
Invoke feature files or JS functions for reusable test logic. Called features can do anything -- HTTP calls, data setup, assertions, or any other Karate operations. For shared setup logic such as authentication or base URLs, see Configuration (karate-config.js). See also Calling Other Features for the call and callonce keywords in Gherkin.
karate.call(path, [arg])
Invoke a feature file or JS function with an optional argument. Supports shared scope via a boolean first argument: karate.call(true, 'helper.feature').
* def result = karate.call('create-user.feature', { name: 'Al' })
* def token = result.authToken
karate.callonce(path, [arg])
Like karate.call() but the result is cached per feature. Subsequent calls with the same path return the cached result.
* def setup = karate.callonce('once-setup.feature')
* def token = setup.token
karate.callSingle(path, [arg])
Like karate.call() but runs only once across the entire test suite. Typically used in karate-config.js for expensive one-time setup such as authentication.
* def auth = karate.callSingle('classpath:auth/login.feature')
* def token = auth.token
Use karate.callSingle() in karate-config.js for expensive one-time setup like authentication tokens. The result is cached across all features in the suite.
HTTP
Make programmatic HTTP requests and access request/response details.
karate.http(url)
Return the HTTP request builder for programmatic use. Lets you construct and invoke HTTP requests entirely from JavaScript.
* def response = karate.http('https://api.example.com').path('users').get()
karate.prevRequest
Access the actual HTTP request object after execution. Contains method, url, headers, and body.
Given url 'https://httpbin.org/post'
And request { key: 'value' }
When method post
* def prev = karate.prevRequest
* match prev.method == 'POST'
karate.proceed([url])
Forward the current request to a target URL. Only available inside a mock scenario (proxy mode). If no URL is provided, the Host header is used.
Scenario: pathMatches('/api/{path}')
* karate.proceed('https://real-backend.example.com')
karate.waitForHttp(url)
Block until the given URL accepts HTTP connections. Useful after starting a server in the background.
* karate.waitForHttp('http://localhost:8080/health')
karate.waitForPort(host, port)
Block until the given host and port accept socket connections.
* karate.waitForPort('localhost', 5432)
Assertions
Validate data programmatically from JavaScript.
karate.expect(actual)
Chai-style BDD assertions familiar to Postman and Mocha users. Supports chaining with .to, .be, .not, .have, and more.
karate.expect(response.name).to.equal('John')
karate.expect(response.age).to.be.above(18)
karate.expect(response).to.have.property('email')
karate.expect(response.tags).to.include('active')
karate.expect(response.status).to.not.equal('deleted')
karate.match(actual, expected) | karate.match(expression)
Programmatic fuzzy match. The two-argument form compares actual against expected. The one-argument form takes a full match expression string. Returns { pass: boolean, message: string }.
* def result = karate.match(response, { id: '#number', name: '#string' })
* if (!result.pass) karate.fail(result.message)
* def r2 = karate.match("response contains { id: '#number' }")
File I/O
Read and write files with support for various formats and path prefixes (classpath:, file:, this:).
karate.read(path)
Read a file with automatic conversion based on extension: JSON, XML, CSV, YAML are parsed; JS files are evaluated; feature files return a callable reference; binary types return byte arrays; everything else returns a string.
* def schema = karate.read('classpath:schemas/user.json')
* def data = karate.read('test-data.csv')
karate.readAsBytes(path)
Read a file as a raw byte array. Useful for binary content such as images or PDFs.
* def bytes = karate.readAsBytes('classpath:files/logo.png')
* match karate.typeOf(bytes) == 'bytes'
karate.readAsStream(path)
Read a file as a Java InputStream. Useful for streaming large files without loading them entirely into memory.
* def stream = karate.readAsStream('classpath:data/large.csv')
karate.readAsString(path)
Read a file as a plain string without any automatic conversion. Useful when you need to process content before parsing.
* def raw = karate.readAsString('classpath:schemas/user.json')
* match karate.typeOf(raw) == 'string'
karate.toAbsolutePath(path)
Resolve a relative or classpath path to an absolute OS file path.
* def abs = karate.toAbsolutePath('classpath:data/test.csv')
* karate.log('Path:', abs)
karate.write(value, path)
Write content to a file relative to the build output directory (e.g., target/). Returns a java.io.File reference.
* def file = karate.write(responseBytes, 'downloads/response.json')
* karate.log('Wrote to:', file.getPath())
Config and Environment
Access configuration, environment, and test metadata.
karate.config
Returns the current configuration settings (from the configure keyword) as an object. This is a copy -- mutations do not affect the running config.
* def cfg = karate.config
* karate.log('Connect timeout:', cfg.connectTimeout)
karate.configure(key, value)
Apply a configuration setting programmatically. Equivalent to the configure keyword.
* karate.configure('connectTimeout', 10000)
* karate.configure('retry', { count: 3, interval: 2000 })
karate.env
The current environment string from -Dkarate.env. Returns null if not set.
* def env = karate.env
* def baseUrl = env == 'staging' ? 'https://staging.api.com' : 'https://api.com'
karate.feature
Current feature metadata including name, description, prefixedPath, fileName, and parentDir.
* karate.log('Feature:', karate.feature.name)
* karate.log('File:', karate.feature.fileName)
karate.info
Scenario information map containing scenarioName, scenarioDescription, featureDir, featureFileName, and errorMessage.
* karate.log('Scenario:', karate.info.scenarioName)
* karate.log('Feature dir:', karate.info.featureDir)
karate.os
OS information object with name (e.g., Mac OS X) and type (windows, macosx, linux, or unknown).
* def isWindows = karate.os.type == 'windows'
* karate.log('Running on:', karate.os.name)
karate.properties
Java system properties map. Read properties passed via -D flags (e.g., -Dapi.port=8080).
* def port = karate.properties['api.port']
* def host = karate.properties['api.host'] || 'localhost'
karate.scenario
Current scenario metadata including name, description, line, sectionIndex, exampleIndex, and exampleData (for scenario outlines).
* karate.log('Scenario:', karate.scenario.name)
* karate.log('Line:', karate.scenario.line)
karate.scenarioOutline
Current scenario outline metadata. Returns null when not in a scenario outline. Includes name, description, line, exampleTableCount, exampleTables, and numScenariosToExecute.
* def outline = karate.scenarioOutline
* if (outline) karate.log('Outline:', outline.name)
karate.tagValues
Tag values in @name=value format as a map of { tagName: [values] }.
* def vals = karate.tagValues
* def envTag = vals['env']
karate.tags
Tags for the current scope (feature-level and scenario-level combined) as an array of strings without the @ prefix.
* def tags = karate.tags
* def isSmoke = karate.filter(tags, t => t == 'smoke').length > 0
Flow Control
Control test execution flow with abort, fail, pause, and setup operations.
karate.abort()
Exit the current scenario early. Typically combined with conditional logic. The scenario is marked as passed (not failed).
* if (responseStatus == 404) karate.abort()
karate.fail(message)
Stop the test with an explicit failure message.
* if (!response.data) karate.fail('Expected data in response')
karate.pause(ms)
Sleep for the given number of milliseconds. By default this is only active during performance testing. Set configure pauseIfNotPerf = true to enable it in normal tests.
* karate.configure('pauseIfNotPerf', true)
* karate.pause(1000)
karate.setup([name])
Call a scenario tagged with @setup. Returns all variables defined in that setup scenario. If name is omitted, the default @setup scenario is used.
* def data = karate.setup()
* def items = data.generatedItems
karate.setupOnce([name])
Like karate.setup() but cached so it runs only once per feature, regardless of how many scenarios call it.
* def data = karate.setupOnce('heavy-setup')
karate.stop(port)
Pause test execution until a socket connection is made to the given port. Intended for debugging UI tests -- remove after use.
* karate.stop(5000)
See Dynamic Scenarios for detailed examples of @setup tag usage with karate.setup() and karate.setupOnce().
Process Execution
Execute OS commands synchronously or asynchronously.
karate.exec(command)
Execute an OS command and block until it completes. Returns stdout as a string. Accepts a string, array of strings, or a config map with line and workingDir.
* def output = karate.exec('git --version')
* def output = karate.exec({ line: 'ls -la', workingDir: '/tmp' })
karate.fork(command)
Start an OS process without blocking. Returns a ProcessHandle with methods like close(), waitSync(), and properties like stdOut, exitCode. Accepts a string, array, or config map with args, listener, errorListener, and start (boolean, default true).
* def proc = karate.fork({ args: ['node', 'server.js'] })
* karate.waitForHttp('http://localhost:3000')
# ... run tests ...
* proc.close()
Async and Events
Work with asynchronous messaging, event channels, and mock servers.
karate.channel(type)
Create a messaging channel of the given type (e.g., 'kafka', 'grpc'). The appropriate Karate extension must be on the classpath. Returns a channel object for publishing and subscribing.
* def kafka = karate.channel('kafka')
* kafka.topic('orders').send({ id: 1, item: 'Book' })
karate.signal(result)
Trigger a signal event for the listen keyword. The passed data becomes available in the listenResult variable. Used for async coordination between threads or callbacks.
* karate.signal({ status: 'done', data: response })
karate.start(pathOrConfig)
Start a mock server from a feature file. Accepts a string path or a config map with keys: mock (path), port, ssl, cert, key, arg, pathPrefix. Returns a mock server object.
* def server = karate.start('mock-api.feature')
* def url = 'http://localhost:' + server.port
* def server = karate.start({ mock: 'api.feature', port: 8443, ssl: true })
For comprehensive mock server documentation, see Test Doubles and Mocking.
Test Data and Utilities
Logging, data generation, type conversion, encoding, and reporting utilities.
karate.doc(path, [vars])
Render an HTML template and insert it into the test report. The path points to a template file. An optional vars map provides template variables.
* karate.doc('classpath:templates/report-section.html')
karate.embed(data, [mimeType], [name])
Embed content (bytes, string, or image) into the JSON report. MIME type is auto-detected if omitted.
* karate.embed(responseBytes, 'image/png', 'screenshot')
karate.faker.*
Built-in test data generation -- no external libraries needed. Returns random realistic values for names, addresses, numbers, and more.
Available methods include: firstName(), lastName(), fullName(), email(), userName(), phoneNumber(), city(), country(), streetAddress(), zipCode(), latitude(), longitude(), randomInt([min], [max]), randomFloat([min], [max]), randomBoolean(), word(), sentence(), paragraph(), alphanumeric([length]), hexColor(), companyName(), jobTitle(), creditCardNumber(), timestamp(), timestampMs(), isoTimestamp().
* def name = karate.faker.firstName()
* def email = karate.faker.email()
* def age = karate.faker.randomInt(18, 65)
* def id = karate.faker.alphanumeric(12)
karate.log(...args)
Log arguments to both the console (SLF4J karate.scenario at INFO level) and the HTML report. JSON and XML are pretty-printed automatically. Equivalent to karate.logger.info() but accepts multiple arguments. For level-aware logging, use karate.logger.debug(), .warn(), .error() instead.
* karate.log('Status:', responseStatus, 'Body:', response)
karate.pretty(value)
Pretty-print a JSON value as a formatted string.
* def formatted = karate.pretty(response)
* karate.log(formatted)
karate.prettyXml(value)
Pretty-print an XML value as a formatted string.
* def formatted = karate.prettyXml(responseXml)
karate.render(path, [vars])
Render an HTML template and return the result as a string, without inserting it into the report. Accepts a path string or a map with a read key.
* def html = karate.render('classpath:templates/email.html', { name: 'Al' })
karate.toBean(json, className)
Convert a JSON object to a Java object of the given fully-qualified class name.
* def pojo = karate.toBean({ name: 'Al', age: 30 }, 'com.example.User')
karate.toBytes(value)
Convert a value (string, JSON, or other) to a byte array.
* def bytes = karate.toBytes('hello world')
karate.toCsv(list)
Convert a JSON array of objects to a CSV string.
* def csv = karate.toCsv([{ name: 'Al', age: 30 }, { name: 'Bo', age: 25 }])
karate.toJava(value)
Convert a JS function to a Java functional interface for interop, or convert JSON to Java List/Map.
* def comparator = karate.toJava((a, b) => a.name < b.name ? -1 : 1)
karate.toJson(object, [stripNulls])
Convert a Java object to JSON. Pass true as the second argument to strip null values.
* def json = karate.toJson(javaPojo)
* def clean = karate.toJson(javaPojo, true)
karate.toString(value)
Convert any value to its string representation.
* def s = karate.toString(123)
* match s == '123'
karate.typeOf(value)
Return the type of a value as a string: null, boolean, number, string, list, map, function, xml, or bytes.
* match karate.typeOf(42) == 'number'
* match karate.typeOf([1]) == 'list'
* match karate.typeOf({ a: 1 }) == 'map'
karate.urlDecode(string)
URL-decode a string.
* def decoded = karate.urlDecode('hello+world+%26+more')
* match decoded == 'hello world & more'
karate.urlEncode(string)
URL-encode a string.
* def encoded = karate.urlEncode('hello world & more')
karate.uuid()
Generate a random UUID string.
* def requestId = karate.uuid()
* header X-Request-Id = requestId
Next Steps
- Test WebSocket connections: WebSocket Testing
- Handle async operations: Polling and Async
- Review conditional logic: Conditional Logic
- Set up test hooks: Hooks and Lifecycle
- Java integration: Java API