kandi background
Explore Kits

karate | Test Automation Made Simple

 by   karatelabs Java Version: v1.2.0.RC6 License: MIT

 by   karatelabs Java Version: v1.2.0.RC6 License: MIT

Download this library from

kandi X-RAY | karate Summary

karate is a Java library. karate has no bugs, it has no vulnerabilities, it has build file available, it has a Permissive License and it has medium support. You can download it from GitHub.
<a><img src="karate-core/src/test/resources/karate-map.jpg" height="650" /></a>. Karate is the only open-source tool to combine API test-automation, [mocks](karate-netty), [performance-testing](karate-gatling) and even [UI automation](karate-core) into a single, unified framework. The BDD syntax popularized by Cucumber is language-neutral, and easy for even non-programmers. Assertions and HTML reports are built-in, and you can run tests in parallel for speed. There’s also a cross-platform [stand-alone executable](karate-netty#standalone-jar) for teams not comfortable with Java. You don’t have to compile code. Just write tests in a simple, readable syntax - carefully designed for HTTP, JSON, GraphQL and XML. And you can mix API and [UI test-automation](karate-core) within the same test script. A [Java API](#java-api) also exists for those who prefer to programmatically integrate Karate’s rich automation and data-assertion capabilities.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • karate has a medium active ecosystem.
  • It has 5840 star(s) with 1528 fork(s). There are 221 watchers for this library.
  • There were 1 major release(s) in the last 6 months.
  • There are 58 open issues and 1534 have been closed. On average issues are closed in 12 days. There are no pull requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of karate is v1.2.0.RC6
karate Support
Best in #Java
Average in #Java
karate Support
Best in #Java
Average in #Java

quality kandi Quality

  • karate has no bugs reported.
karate Quality
Best in #Java
Average in #Java
karate Quality
Best in #Java
Average in #Java

securitySecurity

  • karate has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
karate Security
Best in #Java
Average in #Java
karate Security
Best in #Java
Average in #Java

license License

  • karate is licensed under the MIT License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
karate License
Best in #Java
Average in #Java
karate License
Best in #Java
Average in #Java

buildReuse

  • karate releases are available to install and integrate.
  • Build file is available. You can build the component from source.
  • Installation instructions, examples and code snippets are available.
karate Reuse
Best in #Java
Average in #Java
karate Reuse
Best in #Java
Average in #Java
Top functions reviewed by kandi - BETA

kandi has reviewed karate and discovered the below as its top functions. This is intended to give you an instant insight into karate implemented functionality, and help decide if they suit your requirements.

  • Compares a macro with another expression .
  • Handles a request .
  • Configures the client .
  • Advance the current scenario .
  • Internal helper method .
  • Override this method to handle the request .
  • Adds a multipart .
  • Send a request .
  • Recursively traverses a JSON string .
  • Handles the action request .

karate Key Features

Java knowledge is not required and even non-programmers can write tests

Scripts are plain-text, require no compilation step or IDE, and teams can collaborate using Git / standard SCM

Based on the popular Cucumber / Gherkin standard - with [IDE support](https://github.com/intuit/karate/wiki/IDE-Support) and syntax-coloring options

Elegant [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) syntax 'natively' supports JSON and XML - including [JsonPath](#set) and [XPath](#xpath-functions) expressions

Eliminate the need for 'Java Beans' or 'helper code' to represent payloads and HTTP end-points, and [dramatically reduce the lines of code](https://twitter.com/KarateDSL/status/873035687817117696) needed for a test

Ideal for testing the highly dynamic responses from [GraphQL](http://graphql.org) API-s because of Karate’s built-in [text-manipulation](#text) and [JsonPath](https://github.com/json-path/JsonPath#path-examples) capabilities

Tests are super-readable - as scenario data can be expressed in-line, in human-friendly [JSON](#json), [XML](#xml), Cucumber [Scenario](#the-cucumber-way) Outline [tables](#table), or a [payload builder](#set-multiple) approach [unique to Karate](https://gist.github.com/ptrthomas/d6beb17e92a43220d254af942e3ed3d9)

Express expected results as readable, well-formed JSON or XML, and [assert in a single step](#match) that the entire response payload (no matter how complex or deeply nested) - is as expected

Comprehensive [assertion capabilities](#fuzzy-matching) - and failures clearly report which data element (and path) is not as expected, for easy troubleshooting of even large payloads

[Fully featured debugger](https://github.com/intuit/karate/wiki/IDE-Support#vs-code-karate-plugin) that can step backwards and even [re-play a step while editing it](https://twitter.com/KarateDSL/status/1167533484560142336) - a huge time-saver

Simpler and more [powerful alternative](https://twitter.com/KarateDSL/status/878984854012022784) to JSON-schema for [validating payload structure](#schema-validation) and format - that even supports [cross-field](#referring-to-the-json-root) / domain validation logic

Scripts can [call other scripts](#calling-other-feature-files) - which means that you can easily re-use and maintain authentication and 'set up' flows efficiently, across multiple tests

Embedded JavaScript engine that allows you to build a library of [re-usable functions](#calling-javascript-functions) that suit your specific environment or organization

Re-use of payload-data and user-defined functions across tests is [so easy](#reading-files) - that it becomes a natural habit for the test-developer

Built-in support for [switching configuration](#switching-the-environment) across different environments (e.g. dev, QA, pre-prod)

Support for [data-driven tests](#data-driven-tests) and being able to [tag or group](#tags) tests is built-in, no need to rely on an external framework

Native support for reading [YAML](#yaml) and even [CSV](#csv-files) files - and you can use them for data-driven tests

Standard Java / Maven project structure, and [seamless integration](#command-line) into CI / CD pipelines - and support for [JUnit 5](#junit-5)

Option to use as a light-weight [stand-alone executable](https://github.com/intuit/karate/tree/master/karate-netty#standalone-jar) - convenient for teams not comfortable with Java

Multi-threaded [parallel execution](#parallel-execution), which is a huge time-saver, especially for integration and end-to-end tests

Built-in [test-reports](#test-reports) compatible with Cucumber so that you have the option of using third-party (open-source) maven-plugins for even [better-looking reports](karate-demo#example-report)

Reports include HTTP request and response [logs in-line](#test-reports), which makes [troubleshooting](https://twitter.com/KarateDSL/status/899671441221623809) and [debugging](https://twitter.com/KarateDSL/status/935029435140489216) easier

Easily invoke JDK classes, Java libraries, or re-use custom Java code if needed, for [ultimate extensibility](#calling-java)

Simple plug-in system for [authentication](#http-basic-authentication-example) and HTTP [header management](#configure-headers) that will handle any complex, real-world scenario

[Cross-browser Web UI automation](karate-core) so that you can test all layers of your application with the same framework

Cross platform [Desktop Automation](karate-robot) that can be [mixed into Web Automation flows](https://twitter.com/ptrthomas/status/1215534821234995200) if needed

Option to invoke via a [Java API](#java-api), which means that you can easily [mix Karate into Java projects or legacy UI-automation suites](https://stackoverflow.com/q/47795762/143475)

[Save significant effort](https://twitter.com/ptrthomas/status/986463717465391104) by re-using Karate test-suites as [Gatling performance tests](karate-gatling) that deeply assert that server responses are accurate under load

Gatling integration can hook into [any custom Java code](https://github.com/intuit/karate/tree/master/karate-gatling#custom) - which means that you can perf-test even non-HTTP protocols such as [gRPC](https://github.com/thinkerou/karate-grpc)

Built-in [distributed-testing capability](https://github.com/intuit/karate/wiki/Distributed-Testing) that works for API, UI and even [load-testing](https://github.com/intuit/karate/wiki/Distributed-Testing#gatling) - without needing any complex "grid" infrastructure

[API mocks](karate-netty) or test-doubles that even [maintain CRUD 'state'](https://hackernoon.com/api-consumer-contract-tests-and-test-doubles-with-karate-72c30ea25c18) across multiple calls - enabling TDD for micro-services and [Consumer Driven Contracts](https://martinfowler.com/articles/consumerDrivenContracts.html)

[Async](#async) support that allows you to seamlessly integrate the handling of custom events or listening to message-queues

[Mock HTTP Servlet](karate-mock-servlet) that enables you to test any controller servlet such as Spring Boot / MVC or Jersey / JAX-RS - without having to boot an app-server, and you can use your HTTP integration tests un-changed

Built-in [HTML templating](https://twitter.com/KarateDSL/status/1338892932691070976) so that you can extend your test-reports into readable specifications

Comprehensive support for different flavors of HTTP calls:

[SOAP](#soap-action) / XML requests

HTTPS / [SSL](#configure) - without needing certificates, key-stores or trust-stores

HTTP [proxy server](#configure) support

URL-encoded [HTML-form](#form-field) data

[Multi-part](#multipart-field) file-upload - including multipart/mixed and multipart/related

Browser-like [cookie](#cookie) handling

Full control over HTTP [headers](#header), [path](#path) and query [parameters](#param)

[Re-try](#retry-until) until condition

[Websocket](http://www.websocket.org) [support](#async)

default

copy iconCopydownload iconDownload
  &lt;a href="https://github.com/intuit/karate/wiki/Support"&gt;
    &lt;img src="https://img.shields.io/badge/support-wiki-red.svg"/&gt;
  &lt;/a&gt;
  &lt;a href="https://twitter.com/getkarate"&gt;
    &lt;img src="https://img.shields.io/twitter/follow/getkarate.svg?style=social&amp;label=Follow"/&gt;
  &lt;/a&gt;
  &lt;a href="https://github.com/intuit/karate/stargazers"&gt;
    &lt;img src="https://img.shields.io/github/stars/intuit/karate?style=social"/&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;a href="https://search.maven.org/artifact/com.intuit.karate/karate-core"&gt;
    &lt;img src="https://img.shields.io/maven-central/v/com.intuit.karate/karate-core.svg"/&gt;
  &lt;/a&gt;
  &lt;a href="https://github.com/intuit/karate/actions?query=workflow%3Amaven-build"&gt;
    &lt;img src="https://github.com/intuit/karate/workflows/maven-build/badge.svg"/&gt;
  &lt;/a&gt;
  &lt;a href="https://github.com/intuit/karate/releases"&gt;
    &lt;img src="https://img.shields.io/github/release/intuit/karate.svg"/&gt;
  &lt;/a&gt;
&lt;/div&gt;

Maven

copy iconCopydownload iconDownload
&lt;dependency&gt;
    &lt;groupId&gt;com.intuit.karate&lt;/groupId&gt;
    &lt;artifactId&gt;karate-junit5&lt;/artifactId&gt;
    &lt;version&gt;1.1.0&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;

Gradle

copy iconCopydownload iconDownload
    testCompile 'com.intuit.karate:karate-junit5:1.1.0'

Quickstart

copy iconCopydownload iconDownload
mvn archetype:generate \
-DarchetypeGroupId=com.intuit.karate \
-DarchetypeArtifactId=karate-archetype \
-DarchetypeVersion=1.1.0 \
-DgroupId=com.mycompany \
-DartifactId=myproject

Folder Structure

copy iconCopydownload iconDownload
&lt;build&gt;
    &lt;testResources&gt;
        &lt;testResource&gt;
            &lt;directory&gt;src/test/java&lt;/directory&gt;
            &lt;excludes&gt;
                &lt;exclude&gt;**/*.java&lt;/exclude&gt;
            &lt;/excludes&gt;
        &lt;/testResource&gt;
    &lt;/testResources&gt;
    &lt;plugins&gt;
    ...
    &lt;/plugins&gt;
&lt;/build&gt;

Naming Conventions

copy iconCopydownload iconDownload
src/test/java
    |
    +-- karate-config.js
    +-- logback-test.xml
    +-- some-reusable.feature
    +-- some-classpath-function.js
    +-- some-classpath-payload.json
    |
    \-- animals
        |
        +-- AnimalsTest.java
        |
        +-- cats
        |   |
        |   +-- cats-post.feature
        |   +-- cats-get.feature
        |   +-- cat.json
        |   \-- CatsRunner.java
        |
        \-- dogs
            |
            +-- dog-crud.feature
            +-- dog.json
            +-- some-helper-function.js
            \-- DogsRunner.java

IDE Support

copy iconCopydownload iconDownload
    &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.10&lt;/version&gt;
        &lt;configuration&gt;
            &lt;argLine&gt;-Dfile.encoding=UTF-8&lt;/argLine&gt;
        &lt;/configuration&gt;
    &lt;/plugin&gt;

JUnit 4

copy iconCopydownload iconDownload
package animals.cats;

import com.intuit.karate.junit4.Karate;
import org.junit.runner.RunWith;

@RunWith(Karate.class)
public class CatsRunner {

}

JUnit 5

copy iconCopydownload iconDownload
package karate;

import com.intuit.karate.junit5.Karate;

class SampleTest {

    @Karate.Test
    Karate testSample() {
        return Karate.run("sample").relativeTo(getClass());
    }

    @Karate.Test
    Karate testTags() {
        return Karate.run("tags").tags("@second").relativeTo(getClass());
    }

    @Karate.Test
    Karate testSystemProperty() {
        return Karate.run("classpath:karate/tags.feature")
                .tags("@second")
                .karateEnv("e2e")
                .systemProperty("foo", "bar");
    }

}

JUnit HTML report

copy iconCopydownload iconDownload
html report: (paste into browser to view)
-----------------------------------------
file:///projects/myproject/target/karate-reports/mypackage.myfeature.html

Command Line

copy iconCopydownload iconDownload
mvn test -Dtest=CatsRunner

Command Line - Gradle

copy iconCopydownload iconDownload
test {
    // pull karate options into the runtime
    systemProperty "karate.options", System.properties.getProperty("karate.options")
    // pull karate env into the runtime
    systemProperty "karate.env", System.properties.getProperty("karate.env")
    // ensure tests are always run
    outputs.upToDateWhen { false }
}

Test Suites

copy iconCopydownload iconDownload
mvn test "-Dkarate.options=--tags ~@skipme" -Dtest=AnimalsTest

JUnit 4 Parallel Execution

copy iconCopydownload iconDownload
import com.intuit.karate.Results;
import com.intuit.karate.Runner;
import static org.junit.Assert.*;
import org.junit.Test;

public class TestParallel {

    @Test
    public void testParallel() {
        Results results = Runner.path("classpath:some/package").tags("@smoke").parallel(5);
        assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
    }

}

JUnit 5 Parallel Execution

copy iconCopydownload iconDownload
import com.intuit.karate.Results;
import com.intuit.karate.Runner;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class TestParallel {

    @Test
    void testParallel() {
        Results results = Runner.path("classpath:animals").tags("~@skipme").parallel(5);
        assertEquals(0, results.getFailCount(), results.getErrorMessages());
    }

}

Parallel Stats

copy iconCopydownload iconDownload
======================================================
elapsed:   2.35 | threads:    5 | thread time: 4.98
features:    54 | ignored:   25 | efficiency: 0.42
scenarios:  145 | passed:   145 | failed: 0
======================================================

Logging

copy iconCopydownload iconDownload
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;configuration&gt;

    &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;
        &lt;encoder&gt;
            &lt;pattern&gt;%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern&gt;
        &lt;/encoder&gt;
    &lt;/appender&gt;

    &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;
        &lt;file&gt;target/karate.log&lt;/file&gt;
        &lt;encoder&gt;
            &lt;pattern&gt;%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern&gt;
        &lt;/encoder&gt;
    &lt;/appender&gt;

    &lt;logger name="com.intuit.karate" level="DEBUG"/&gt;

    &lt;root level="info"&gt;
        &lt;appender-ref ref="STDOUT" /&gt;
        &lt;appender-ref ref="FILE" /&gt;
    &lt;/root&gt;

&lt;/configuration&gt;

Classpath

copy iconCopydownload iconDownload
function fn() {
  var env = karate.env; // get java system property 'karate.env'
  karate.log('karate.env system property was:', env);
  if (!env) {
    env = 'dev'; // a custom 'intelligent' default
  }
  var config = { // base config JSON
    appId: 'my.app.id',
    appSecret: 'my.secret',
    someUrlBase: 'https://some-host.com/v1/auth/',
    anotherUrlBase: 'https://another-host.com/v1/'
  };
  if (env == 'stage') {
    // over-ride only those that need to be
    config.someUrlBase = 'https://stage-host/v1/auth';
  } else if (env == 'e2e') {
    config.someUrlBase = 'https://e2e-host/v1/auth';
  }
  // don't waste time waiting for a connection or if servers don't respond within 5 seconds
  karate.configure('connectTimeout', 5000);
  karate.configure('readTimeout', 5000);
  return config;
}

Switching the Environment

copy iconCopydownload iconDownload
mvn test -DargLine="-Dkarate.env=e2e"

Script Structure

copy iconCopydownload iconDownload
Feature: brief description of what is being tested
    more lines of description if needed.

Background:
  # this section is optional !
  # steps here are executed before each Scenario in this file
  # variables defined here will be 'global' to all scenarios
  # and will be re-initialized before every scenario

Scenario: brief description of this scenario
  # steps for this scenario

Scenario: a different scenario
  # steps for this other scenario

Set a named variable

copy iconCopydownload iconDownload
# assigning a string value:
Given def myVar = 'world'

# using a variable
Then print myVar

# assigning a number (you can use '*' instead of Given / When / Then)
* def myNum = 5

Assert if an expression evaluates to

copy iconCopydownload iconDownload
Given def color = 'red '
And def num = 5
Then assert color + num == 'red 5'

Log to the console

copy iconCopydownload iconDownload
* print 'the value of a is:', a

JSON

copy iconCopydownload iconDownload
* def cat = { name: 'Billie', scores: [2, 5] }
* assert cat.scores[1] == 5

XML

copy iconCopydownload iconDownload
Given def cat = &lt;cat&gt;&lt;name&gt;Billie&lt;/name&gt;&lt;scores&gt;&lt;score&gt;2&lt;/score&gt;&lt;score&gt;5&lt;/score&gt;&lt;/scores&gt;&lt;/cat&gt;
# sadly, xpath list indexes start from 1
Then match cat/cat/scores/score[2] == '5'
# but karate allows you to traverse xml like json !!
Then match cat.cat.scores.score[1] == 5

Embedded Expressions

copy iconCopydownload iconDownload
Given def user = { name: 'john', age: 21 }
And def lang = 'en'
When def session = { name: '#(user.name)', locale: '#(lang)', sessionUser: '#(user)'  }

Enclosed JavaScript

copy iconCopydownload iconDownload
When def user = { name: 'john', age: 21 }
And def lang = 'en'

* def embedded = { name: '#(user.name)', locale: '#(lang)', sessionUser: '#(user)' }
* def enclosed = ({ name: user.name, locale: lang, sessionUser: user })
* match embedded == enclosed

Multi-Line Expressions

copy iconCopydownload iconDownload
# instead of:
* def cat = &lt;cat&gt;&lt;name&gt;Billie&lt;/name&gt;&lt;scores&gt;&lt;score&gt;2&lt;/score&gt;&lt;score&gt;5&lt;/score&gt;&lt;/scores&gt;&lt;/cat&gt;

# this is more readable:
* def cat =
  """
  &lt;cat&gt;
      &lt;name&gt;Billie&lt;/name&gt;
      &lt;scores&gt;
          &lt;score&gt;2&lt;/score&gt;
          &lt;score&gt;5&lt;/score&gt;
      &lt;/scores&gt;
  &lt;/cat&gt;
  """
# example of a request payload in-line
Given request
  """
  &lt;?xml version='1.0' encoding='UTF-8'?&gt;
  &lt;S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  &lt;S:Body&gt;
  &lt;ns2:QueryUsageBalance xmlns:ns2="http://www.mycompany.com/usage/V1"&gt;
      &lt;ns2:UsageBalance&gt;
          &lt;ns2:LicenseId&gt;12341234&lt;/ns2:LicenseId&gt;
      &lt;/ns2:UsageBalance&gt;
  &lt;/ns2:QueryUsageBalance&gt;
  &lt;/S:Body&gt;
  &lt;/S:Envelope&gt;
  """

# example of a payload assertion in-line
Then match response ==
  """
  { id: { domain: "DOM", type: "entityId", value: "#ignore" },
    created: { on: "#ignore" },
    lastUpdated: { on: "#ignore" },
    entityState: "ACTIVE"
  }
  """

A simple way to create JSON Arrays

copy iconCopydownload iconDownload
* table cats
  | name   | age |
  | 'Bob'  | 2   |
  | 'Wild' | 4   |
  | 'Nyan' | 3   |

* match cats == [{name: 'Bob', age: 2}, {name: 'Wild', age: 4}, {name: 'Nyan', age: 3}]

Don’t parse, treat as raw text

copy iconCopydownload iconDownload
Scenario Outline:
  # note the 'text' keyword instead of 'def'
  * text query =
    """
    {
      hero(name: "&lt;name&gt;") {
        height
        mass
      }
    }
    """
  Given path 'graphql'
  And request { query: '#(query)' }
  And header Accept = 'application/json'
  When method post
  Then status 200

  Examples:
    | name  |
    | John  |
    | Smith |

Text Placeholder Replacement

copy iconCopydownload iconDownload
* def text = 'hello &lt;foo&gt; world'
* replace text.foo = 'bar'
* match text == 'hello bar world'

YAML Files

copy iconCopydownload iconDownload
# yaml from a file (the extension matters), and the data-type of 'bar' would be JSON
* def bar = read('data.yaml')

CSV Files

copy iconCopydownload iconDownload
* text foo =
    """
    name,type
    Billie,LOL
    Bob,Wild
    """
* csv bar = foo
* match bar == [{ name: 'Billie', type: 'LOL' }, { name: 'Bob', type: 'Wild' }]

JavaScript Functions

copy iconCopydownload iconDownload
* def greeter = function(title, name) { return 'hello ' + title + ' ' + name }
* assert greeter('Mr.', 'Bob') == 'hello Mr. Bob'

Java Interop

copy iconCopydownload iconDownload
* def dateStringToLong =
  """
  function(s) {
    var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
    var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    return sdf.parse(s).time; // '.getTime()' would also have worked instead of '.time'
  }
  """
* assert dateStringToLong("2016-12-24T03:39:21.081+0000") == 1482550761081

Reading Files

copy iconCopydownload iconDownload
# json
* def someJson = read('some-json.json')
* def moreJson = read('classpath:more-json.json')

# xml
* def someXml = read('../common/my-xml.xml')

# import yaml (will be converted to json)
* def jsonFromYaml = read('some-data.yaml')

# csv (will be converted to json)
* def jsonFromCsv = read('some-data.csv')

# string
* def someString = read('classpath:messages.txt')

# javascript (will be evaluated)
* def someValue = read('some-js-code.js')

# if the js file evaluates to a function, it can be re-used later using the 'call' keyword
* def someFunction = read('classpath:some-reusable-code.js')
* def someCallResult = call someFunction

# the following short-cut is also allowed
* def someCallResult = call read('some-js-code.js')

Read File As String

copy iconCopydownload iconDownload
Given path 'upload'
And header Content-Type = 'text/csv'
And request karate.readAsString('classpath:my.csv')
When method post
Then status 202

Floats and Integers

copy iconCopydownload iconDownload
* def foo = '10'
* string json = { bar: '#(1 * foo)' }
* match json == '{"bar":10.0}'

* string json = { bar: '#(parseInt(foo))' }
* match json == '{"bar":10.0}'

Large Numbers

copy iconCopydownload iconDownload
* def big = 123123123123
* string json = { num: '#(big)' }
* match json == '{"num":1.23123123123E11}'

Karate Expressions

copy iconCopydownload iconDownload
 Example | Shape | Description
-------- | ----- | -----------
`* def foo = 'bar'` | JS | simple strings, numbers or booleans
`* def foo = 'bar' + baz[0]` | JS | any valid JavaScript expression, and variables can be mixed in, another example: `bar.length + 1`
`* def foo = { bar: '#(baz)' }` | JSON | anything that starts with a `{` or a `[` is parsed as JSON, use [`text`](#text) instead of [`def`](#def) if you need to suppress the default behavior
`* def foo = ({ bar: baz })` | JS | [enclosed JavaScript](#enclosed-javascript), the result of which is exactly equivalent to the above
`* def foo = &lt;foo&gt;bar&lt;/foo&gt;` | XML | anything that starts with a `&lt;` is parsed as XML, use [`text`](#text) instead of [`def`](#def) if you need to suppress the default behavior
`* def foo = function(arg){ return arg + bar }` | JS Fn | anything that starts with `function(...){` is parsed as a JS function.
`* def foo = read('bar.json')` | JS | using the built-in [`read()`](#reading-files) function
`* def foo = $.bar[0]` | JsonPath | short-cut JsonPath on the [`response`](#response)
`* def foo = /bar/baz` | XPath | short-cut XPath on the [`response`](#response)
`* def foo = get bar $..baz[?(@.ban)]` | [`get`](#get) JsonPath | [JsonPath](https://github.com/json-path/JsonPath#path-examples) on the variable `bar`, you can also use [`get[0]`](#get-plus-index) to get the first item if the JsonPath evaluates to an array - especially useful when using wildcards such as `[*]` or [filter-criteria](#jsonpath-filters)
`* def foo = $bar..baz[?(@.ban)]` | $var.JsonPath | [convenience short-cut](#get-short-cut) for the above
`* def foo = get bar count(/baz//ban)` | [`get`](#get) XPath | XPath on the variable `bar`
`* def foo = karate.pretty(bar)` | JS | using the [built-in `karate` object](#the-karate-object) in JS expressions
`* def Foo = Java.type('com.mycompany.Foo')` | JS-Java | [Java Interop](#java-interop), and even package-name-spaced one-liners like `java.lang.System.currentTimeMillis()` are possible
`* def foo = call bar { baz: '#(ban)' }` | [`call`](#call) | or [`callonce`](#callonce), where expressions like [`read('foo.js')`](#reading-files) are allowed as the object to be called or the argument
`* def foo = bar({ baz: ban })` | JS | equivalent to the above, JavaScript function invocation

Core Keywords

copy iconCopydownload iconDownload
Given url 'https://myhost.com/v1/cats'

Keywords that set key-value pairs

copy iconCopydownload iconDownload
Given param someKey = 'hello'
And param anotherKey = someVariable

Keywords that set multiple key-value pairs in one step

copy iconCopydownload iconDownload
* params { searchBy: 'client', active: true, someList: [1, 2, 3] }

SOAP

copy iconCopydownload iconDownload
Given request read('soap-request.xml')
When soap action 'QueryUsageBalance'
Then status 200
And match response /Envelope/Body/QueryUsageBalanceResponse/Result/Error/Code == 'DAT_USAGE_1003'
And match response /Envelope/Body/QueryUsageBalanceResponse == read('expected-response.xml')

Managing Headers, SSL, Timeouts and HTTP Proxy

copy iconCopydownload iconDownload
 Key | Type | Description
------ | ---- | ---------
`headers` | JSON / JS function | See [`configure headers`](#configure-headers)
`cookies` | JSON / JS function | Just like `configure headers`, but for cookies. You will typically never use this, as response cookies are auto-added to all future requests. If you need to clear cookies at any time, just do `configure cookies = null`
`logPrettyRequest` | boolean | Pretty print the request payload JSON or XML with indenting (default `false`)
`logPrettyResponse` | boolean | Pretty print the response payload JSON or XML with indenting (default `false`)
`printEnabled` | boolean | Can be used to suppress the [`print`](#print) output when not in 'dev mode' by setting as `false` (default `true`)
`report` | JSON / boolean | see [report verbosity](#report-verbosity)
`afterScenario` | JS function | Will be called [after every `Scenario`](#hooks) (or `Example` within a `Scenario Outline`), refer to this example: [`hooks.feature`](karate-demo/src/test/java/demo/hooks/hooks.feature)
`afterFeature` | JS function | Will be called [after every `Feature`](#hooks), refer to this example: [`hooks.feature`](karate-demo/src/test/java/demo/hooks/hooks.feature)
`ssl` | boolean | Enable HTTPS calls without needing to configure a trusted certificate or key-store.
`ssl` | string | Like above, but force the SSL algorithm to one of [these values](http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext). (The above form internally defaults to `TLS` if simply set to `true`).
`ssl` | JSON | see [X509 certificate authentication](#x509-certificate-authentication)
`followRedirects` | boolean | Whether the HTTP client automatically follows redirects - (default `true`), refer to this [example](karate-demo/src/test/java/demo/redirect/redirect.feature).
`connectTimeout` | integer | Set the connect timeout (milliseconds). The default is 30000 (30 seconds). Note that for `karate-apache`, this sets the [socket timeout](https://stackoverflow.com/a/22722260/143475) to the same value as well.
`readTimeout` | integer | Set the read timeout (milliseconds). The default is 30000 (30 seconds).
`proxy` | string | Set the URI of the HTTP proxy to use.
`proxy` | JSON | For a proxy that requires authentication, set the `uri`, `username` and `password`, see example below. Also a `nonProxyHosts` key is supported which can take a list for e.g. `{ uri: 'http://my.proxy.host:8080',  nonProxyHosts: ['host1', 'host2']}`
`localAddress` | string | see [`karate-gatling`](karate-gatling#configure-localaddress)
`charset` | string | The charset that will be sent in the request `Content-Type` which defaults to `utf-8`. You typically never need to change this, and you can over-ride (or disable) this per-request if needed via the [`header`](#header) keyword ([example](karate-demo/src/test/java/demo/headers/content-type.feature)).
`retry` | JSON | defaults to `{ count: 3, interval: 3000 }` - see [`retry until`](#retry-until)
`callSingleCache` | JSON | defaults to `{ minutes: 0, dir: 'target' }` - see [`configure callSingleCache`](#configure-callsinglecache)
`lowerCaseResponseHeaders` | boolean | Converts every key in the [`responseHeaders`](#responseheaders) to lower-case which makes it easier to validate or re-use
`abortedStepsShouldPass` | boolean | defaults to `false`, whether steps after a [`karate.abort()`](#karate-abort) should be marked as `PASSED` instead of `SKIPPED` - this can impact the behavior of 3rd-party reports, see [this issue](https://github.com/intuit/karate/issues/755) for details
`logModifier` | Java Object | See [Log Masking](#log-masking)
`responseHeaders` | JSON / JS function | See [`karate-netty`](karate-netty#configure-responseheaders)
`cors` | boolean | See [`karate-netty`](karate-netty#configure-cors)
`driver` | JSON | See [UI Automation](karate-core)
`driverTarget` | JSON / Java Object | See [`configure driverTarget`](karate-core#configure-drivertarget)
`pauseIfNotPerf` | boolean | defaults to `false`, relevant only for performance-testing, see [`karate.pause()`](#karate-pause) and [`karate-gatling`](karate-gatling#think-time)

Report Verbosity

copy iconCopydownload iconDownload
* configure report = { showLog: true, showAllSteps: false }

Log Masking

copy iconCopydownload iconDownload
# if this was in karate-config.js, it would apply "globally"
* def LM = Java.type('demo.headers.DemoLogModifier')
* configure logModifier = new LM()

X509 Certificate Authentication

copy iconCopydownload iconDownload
# enable X509 certificate authentication with PKCS12 file 'certstore.pfx' and password 'certpassword'
* configure ssl = { keyStore: 'classpath:certstore.pfx', keyStorePassword: 'certpassword', keyStoreType: 'pkcs12' }

JS for JSON

copy iconCopydownload iconDownload
* def myJson = { a: '1' }
* myJson.b = 2
* match myJson == { a: '1', b: 2 }

Manipulating Data

copy iconCopydownload iconDownload
* def myJson = { foo: 'bar' }
* set myJson.foo = 'world'
* match myJson == { foo: 'world' }

# add new keys.  you can use pure JsonPath expressions (notice how this is different from the above)
* set myJson $.hey = 'ho'
* match myJson == { foo: 'world', hey: 'ho' }

# and even append to json arrays (or create them automatically)
* set myJson.zee[0] = 5
* match myJson == { foo: 'world', hey: 'ho', zee: [5] }

# omit the array index to append
* set myJson.zee[] = 6
* match myJson == { foo: 'world', hey: 'ho', zee: [5, 6] }

# nested json ? no problem
* set myJson.cat = { name: 'Billie' }
* match myJson == { foo: 'world', hey: 'ho', zee: [5, 6], cat: { name: 'Billie' } }

# and for match - the order of keys does not matter
* match myJson == { cat: { name: 'Billie' }, hey: 'ho', foo: 'world', zee: [5, 6] }

# you can ignore fields marked with '#ignore'
* match myJson == { cat: '#ignore', hey: 'ho', foo: 'world', zee: [5, 6] }

Ignore or Validate

copy iconCopydownload iconDownload
* def cat = { name: 'Billie', type: 'LOL', id: 'a9f7a56b-8d5c-455c-9d13-808461d17b91' }
* match cat == { name: '#ignore', type: '#regex [A-Z]{3}', id: '#uuid' }
# this will fail
# * match cat == { name: '#ignore', type: '#regex .{2}', id: '#uuid' }

Optional Fields

copy iconCopydownload iconDownload
* def foo = { bar: 'baz' }
* match foo == { bar: '#string', ban: '##string' }

Remove If Null

copy iconCopydownload iconDownload
* def data = { a: 'hello', b: null, c: null }
* def json = { foo: '#(data.a)', bar: '#(data.b)', baz: '##(data.c)' }
* match json == { foo: 'hello', bar: null }

'Self' Validation Expressions

copy iconCopydownload iconDownload
* def date = { month: 3 }
* match date == { month: '#? _ &gt; 0 &amp;&amp; _ &lt; 13' }

Matching Sub-Sets of JSON Keys and Arrays

copy iconCopydownload iconDownload
* def foo = { bar: 1, baz: 'hello', ban: 'world' }

* match foo contains { bar: 1 }
* match foo contains { baz: 'hello' }
* match foo contains { bar:1, baz: 'hello' }
# this will fail
# * match foo == { bar:1, baz: 'hello' }

(not)

copy iconCopydownload iconDownload
* def foo = { bar: 1, baz: 'hello', ban: 'world' }
* match foo !contains { bar: 2 }
* match foo !contains { huh: '#notnull' }

Validate every element in a JSON array

copy iconCopydownload iconDownload
* def data = { foo: [{ bar: 1, baz: 'a' }, { bar: 2, baz: 'b' }, { bar: 3, baz: 'c' }]}

* match each data.foo == { bar: '#number', baz: '#string' }

# and you can use 'contains' the way you'd expect
* match each data.foo contains { bar: '#number' }
* match each data.foo contains { bar: '#? _ != 4' }

# some more examples of validation macros
* match each data.foo contains { baz: "#? _ != 'z'" }
* def isAbc = function(x) { return x == 'a' || x == 'b' || x == 'c' }
* match each data.foo contains { baz: '#? isAbc(_)' }

# this is also possible, see the subtle difference from the above
* def isXabc = function(x) { return x.baz == 'a' || x.baz == 'b' || x.baz == 'c' }
* match each data.foo == '#? isXabc(_)'

Schema Validation

copy iconCopydownload iconDownload
* def foo = ['bar', 'baz']

# should be an array
* match foo == '#[]'

# should be an array of size 2
* match foo == '#[2]'

# should be an array of strings with size 2
* match foo == '#[2] #string'

# each array element should have a 'length' property with value 3
* match foo == '#[]? _.length == 3'

# should be an array of strings each of length 3
* match foo == '#[] #string? _.length == 3'

# should be null or an array of strings
* match foo == '##[] #string'

JsonPath filters

copy iconCopydownload iconDownload
* def cat =
  """
  {
    name: 'Billie',
    kittens: [
      { id: 23, name: 'Bob' },
      { id: 42, name: 'Wild' }
    ]
  }
  """
# find single kitten where id == 23
* def bob = get[0] cat.kittens[?(@.id==23)]
* match bob.name == 'Bob'

# using the karate object if the expression is dynamic
* def temp = karate.jsonPath(cat, "$.kittens[?(@.name=='" + bob.name + "')]")
* match temp[0] == bob

# or alternatively
* def temp = karate.jsonPath(cat, "$.kittens[?(@.name=='" + bob.name + "')]")[0]
* match temp == bob

JSON Transforms

copy iconCopydownload iconDownload
Scenario: karate map operation
    * def fun = function(x){ return x * x }
    * def list = [1, 2, 3]
    * def res = karate.map(list, fun)
    * match res == [1, 4, 9]

Scenario: convert an array into a different shape
    * def before = [{ foo: 1 }, { foo: 2 }, { foo: 3 }]
    * def fun = function(x){ return { bar: x.foo } }
    * def after = karate.map(before, fun)
    * match after == [{ bar: 1 }, { bar: 2 }, { bar: 3 }]

Scenario: convert array of primitives into array of objects
    * def list = [ 'Bob', 'Wild', 'Nyan' ]
    * def data = karate.mapWithKey(list, 'name')
    * match data == [{ name: 'Bob' }, { name: 'Wild' }, { name: 'Nyan' }]

Scenario: karate filter operation
    * def fun = function(x){ return x % 2 == 0 }
    * def list = [1, 2, 3, 4]
    * def res = karate.filter(list, fun)
    * match res == [2, 4]

Scenario: forEach works even on object key-values, not just arrays
    * def keys = []
    * def vals = []
    * def idxs = []
    * def fun =
    """
    function(x, y, i) {
      karate.appendTo(keys, x);
      karate.appendTo(vals, y);
      karate.appendTo(idxs, i);
    }
    """
    * def map = { a: 2, b: 4, c: 6 }
    * karate.forEach(map, fun)
    * match keys == ['a', 'b', 'c']
    * match vals == [2, 4, 6]
    * match idxs == [0, 1, 2]

Scenario: filterKeys
    * def schema = { a: '#string', b: '#number', c: '#boolean' }
    * def response = { a: 'x', c: true }
    # very useful for validating a response against a schema "super-set"
    * match response == karate.filterKeys(schema, response)
    * match karate.filterKeys(response, 'b', 'c') == { c: true }
    * match karate.filterKeys(response, ['a', 'b']) == { a: 'x' }

Scenario: merge
    * def foo = { a: 1 }
    * def bar = karate.merge(foo, { b: 2 })
    * match bar == { a: 1, b: 2 }

Scenario: append
    * def foo = [{ a: 1 }]
    * def bar = karate.append(foo, { b: 2 })
    * match bar == [{ a: 1 }, { b: 2 }]

Scenario: sort
    * def foo = [{a: { b: 3 }}, {a: { b: 1 }}, {a: { b: 2 }}]
    * def fun = function(x){ return x.a.b }
    * def bar = karate.sort(foo, fun)
    * match bar == [{a: { b: 1 }}, {a: { b: 2 }}, {a: { b: 3 }}]
    * match bar.reverse() == [{a: { b: 3 }}, {a: { b: 2 }}, {a: { b: 1 }}]

Loops

copy iconCopydownload iconDownload
* def fun = function(i){ return i * 2 }
* def foo = karate.repeat(5, fun)
* match foo == [0, 2, 4, 6, 8]

* def foo = []
* def fun = function(i){ karate.appendTo(foo, i) }
* karate.repeat(5, fun)
* match foo == [0, 1, 2, 3, 4]

# generate test data easily
* def fun = function(i){ return { name: 'User ' + (i + 1) } }
* def foo = karate.repeat(3, fun)
* match foo == [{ name: 'User 1' }, { name: 'User 2' }, { name: 'User 3' }]

# generate a range of numbers as a json array
* def foo = karate.range(4, 9)
* match foo == [4, 5, 6, 7, 8, 9]

XPath Functions

copy iconCopydownload iconDownload
* def myXml =
  """
  &lt;records&gt;
    &lt;record index="1"&gt;a&lt;/record&gt;
    &lt;record index="2"&gt;b&lt;/record&gt;
    &lt;record index="3" foo="bar"&gt;c&lt;/record&gt;
  &lt;/records&gt;
  """

* match foo count(/records//record) == 3
* match foo //record[@index=2] == 'b'
* match foo //record[@foo='bar'] == 'c'

Advanced XPath

copy iconCopydownload iconDownload
* def teachers =
  """
  &lt;teachers&gt;
    &lt;teacher department="science"&gt;
      &lt;subject&gt;math&lt;/subject&gt;
      &lt;subject&gt;physics&lt;/subject&gt;
    &lt;/teacher&gt;
    &lt;teacher department="arts"&gt;
      &lt;subject&gt;political education&lt;/subject&gt;
      &lt;subject&gt;english&lt;/subject&gt;
    &lt;/teacher&gt;
  &lt;/teachers&gt;
  """
* match teachers //teacher[@department='science']/subject == ['math', 'physics']

Special Variables

copy iconCopydownload iconDownload
# the three lines below are equivalent
Then match response $ == { name: 'Billie' }
Then match response == { name: 'Billie' }
Then match $ == { name: 'Billie' }

# the three lines below are equivalent
Then match response.name == 'Billie'
Then match response $.name == 'Billie'
Then match $.name == 'Billie'

HTTP Header Manipulation

copy iconCopydownload iconDownload
function fn() {
  var uuid = '' + java.util.UUID.randomUUID(); // convert to string
  var out = { // so now the txid_header would be a unique uuid for each request
    txid_header: uuid,
    ip_header: '123.45.67.89', // hard coded here, but also can be as dynamic as you want
  };
  var authString = '';
  var authToken = karate.get('authToken'); // use the 'karate' helper to do a 'safe' get of a 'dynamic' variable
  if (authToken) { // and if 'authToken' is not null ...
    authString = ',auth_type=MyAuthScheme'
        + ',auth_key=' + authToken.key
        + ',auth_user=' + authToken.userId
        + ',auth_project=' + authToken.projectId;
  }
  // the 'appId' variable here is expected to have been set via karate-config.js (bootstrap init) and will never change
  out['Authorization'] = 'My_Auth app_id=' + appId + authString;
  return out;
}

Calling other

copy iconCopydownload iconDownload
Feature: which makes a 'call' to another re-usable feature

Background:
  * configure headers = read('classpath:my-headers.js')
  * def signIn = call read('classpath:my-signin.feature') { username: 'john', password: 'secret' }
  * def authToken = signIn.authToken

Scenario: some scenario
  # main test steps

Call Tag Selector

copy iconCopydownload iconDownload
call read('classpath:my-signin.feature@name=someScenarioName')

Data-Driven Features

copy iconCopydownload iconDownload
* table kittens
  | name   | age |
  | 'Bob'  |   2 |
  | 'Wild' |   1 |
  | 'Nyan' |   3 |

* def result = call read('cat-create.feature') kittens
* def created = $result[*].response
* match each created == { id: '#number', name: '#string', age: '#number' }
* match created[*].name contains only ['Bob', 'Wild', 'Nyan']

Default Values

copy iconCopydownload iconDownload
# if foo is not defined, it will default to 42
* def foo = karate.get('foo', 42)

JS function argument rules for

copy iconCopydownload iconDownload
* def adder = function(a, b){ return a + b }
* assert adder(1, 2) == 3

Return types

copy iconCopydownload iconDownload
* def returnValue = call myFunction

Calling Java

copy iconCopydownload iconDownload
package com.mycompany;

import java.util.HashMap;
import java.util.Map;

public class JavaDemo {

    public Map&lt;String, Object&gt; doWork(String fromJs) {
        Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();
        map.put("someKey", "hello " + fromJs);
        return map;
    }

    public static String doWorkStatic(String fromJs) {
        return "hello " + fromJs;
    }

}

Conditional Logic

copy iconCopydownload iconDownload
* def filename = zone == 'zone1' ? 'test1.feature' : 'test2.feature'
* def result = call read(filename)

JSON Lookup

copy iconCopydownload iconDownload
* def data =
"""
{
   foo: 'hello',
   bar: 'world'
}
"""
# in real-life key can be dynamic
* def key = 'bar'
# and used to lookup data
* match (data[key]) == 'world'

Abort and Fail

copy iconCopydownload iconDownload
* if (responseStatus == 404) karate.abort()

Commonly Needed Utilities

copy iconCopydownload iconDownload
* def getDate =
  """
  function() {
    var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
    var sdf = new SimpleDateFormat('yyyy/MM/dd');
    var date = new java.util.Date();
    return sdf.format(date);
  }
  """

* def temp = getDate()
* print temp

Multiple Functions in One File

copy iconCopydownload iconDownload
@ignore
Feature:

Scenario:
  * def hello = function(){ return 'hello' }
  * def world = function(){ return 'world' }

Async

copy iconCopydownload iconDownload
Background:
* def QueueConsumer = Java.type('mock.contract.QueueConsumer')
* def queue = new QueueConsumer(queueName)
* def handler = function(msg){ karate.signal(msg) }
* queue.listen(karate.toJava(handler))
* url paymentServiceUrl + '/payments'

Scenario: create, get, update, list and delete payments
    Given request { amount: 5.67, description: 'test one' }
    When method post
    Then status 200
    And match response == { id: '#number', amount: 5.67, description: 'test one' }
    And def id = response.id
    * listen 5000
    * json shipment = listenResult
    * print '### received:', shipment
    * match shipment == { paymentId: '#(id)', status: 'shipped' }

Java Function References

copy iconCopydownload iconDownload
public class Hello {

    public static String sayHello(String message) {
        return "hello " + message;
    }

    public static Function&lt;String, String&gt; sayHelloFactory() {
        return s -&gt; sayHello(s);
    }

}

WebSocket

copy iconCopydownload iconDownload
* def handler = function(msg){ return msg.startsWith('hello') }
* def socket = karate.webSocket(demoBaseUrl + '/websocket', handler)
* socket.send('Billie')
* def result = socket.listen(5000)
* match result == 'hello Billie !'

Environment Tags

copy iconCopydownload iconDownload
@env=dev
Scenario: runs only when karate.env is 'dev'
* print 'karate.env is:', karate.env

Tags And Examples

copy iconCopydownload iconDownload
Scenario Outline: examples partitioned by tag
* def vals = karate.tagValues
* match vals.region[0] == expected

  @region=US
  Examples:
    | expected |
    | US       |

  @region=GB
  Examples:
    | expected |
    | GB       |

jbang

copy iconCopydownload iconDownload
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.intuit.karate:karate-core:RELEASE

import com.intuit.karate.*;
import java.util.List;

public class javadsl {

    public static void main(String[] args) {
        List users = Http.to("https://jsonplaceholder.typicode.com/users")
                .get().json().asList();
        Match.that(users.get(0)).contains("{ name: 'Leanne Graham' }");
        String city = Json.of(users).get("$[0].address.city");
        Match.that("Gwenborough").isEqualTo(city);
        System.out.println("\n*** second user: " + Json.of(users.get(1)).toString());
    }

}

Hooks

copy iconCopydownload iconDownload
var result = karate.callSingle('classpath:some/package/my.feature');

The Cucumber Way

copy iconCopydownload iconDownload
Feature: karate answers 2

Background:
  * url 'http://localhost:8080'

Scenario Outline: given circuit name, validate country
  Given path 'api/f1/circuits/&lt;name&gt;.json'
  When method get
  Then match $.MRData.CircuitTable.Circuits[0].Location.country == '&lt;country&gt;'

  Examples:
    | name   | country  |
    | monza  | Italy    |
    | spa    | Belgium  |
    | sepang | Malaysia |

Scenario Outline: given race number, validate number of pitstops for Max Verstappen in 2015
  Given path 'api/f1/2015/&lt;race&gt;/drivers/max_verstappen/pitstops.json'
  When method get
  Then assert response.MRData.RaceTable.Races[0].PitStops.length == &lt;stops&gt;

  Examples:
    | race | stops |
    | 1    | 1     |
    | 2    | 3     |
    | 3    | 2     |
    | 4    | 2     |

Scenario Outline Enhancements

copy iconCopydownload iconDownload
Scenario Outline: name is &lt;name&gt; and age is &lt;age&gt;
  * def temp = '&lt;name&gt;'
  * match temp == name
  * match temp == __row.name
  * def expected = __num == 0 ? 'name is Bob and age is 5' : 'name is Nyan and age is 6'
  * match expected == karate.scenario.name

  Examples:
    | name | age |
    | Bob  | 5   |
    | Nyan | 6   |

Scenario Outline: magic variables with type hints
  * def expected = [{ name: 'Bob', age: 5 }, { name: 'Nyan', age: 6 }]
  * match __row == expected[__num]

  Examples:
    | name | age! |
    | Bob  | 5    |
    | Nyan | 6    |

Scenario Outline: embedded expressions and type hints
  * match __row == { name: '#(name)', alive: '#boolean' }

  Examples:
    | name | alive! |
    | Bob  | false  |
    | Nyan | true   |

Scenario Outline: inline json
  * match __row == { first: 'hello', second: { a: 1 } }
  * match first == 'hello'
  * match second == { a: 1 }

  Examples:
    | first  | second!  |
    | hello  | { a: 1 } |

Dynamic Scenario Outline

copy iconCopydownload iconDownload
Feature: scenario outline using a dynamic table

Background:
    * def kittens = read('../callarray/kittens.json')

Scenario Outline: cat name: &lt;name&gt;
    Given url demoBaseUrl
    And path 'cats'
    And request { name: '#(name)' }
    When method post
    Then status 200
    And match response == { id: '#number', name: '#(name)' }

    # the single cell can be any valid karate expression
    # and even reference a variable defined in the Background
    Examples:
    | kittens |

Community Discussions

No Community Discussions are available at this moment for karate.Refer to stack overflow page for discussions.

No Community Discussions are available at this moment for karate.Refer to stack overflow page for discussions.

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install karate

If you are a Java developer - Karate requires at least [Java](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 8 and then either [Maven](http://maven.apache.org), [Gradle](https://gradle.org), [Eclipse](#eclipse-quickstart) or [IntelliJ](https://github.com/intuit/karate/wiki/IDE-Support#intellij-community-edition) to be installed. Note that Karate works fine on OpenJDK. If you are new to programming or test-automation, refer to this video for [getting started with just the (free) IntelliJ Community Edition](https://youtu.be/W-af7Cd8cMc). Other options are the [quickstart](#quickstart) or the [standalone executable](karate-netty#standalone-jar). If you don’t want to use Java, you have the option of just downloading and extracting the [ZIP release](https://github.com/intuit/karate/wiki/ZIP-Release). Try this especially if you don’t have much experience with programming or test-automation. We recommend that you use the [Karate extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=kirkslota.karate-runner) - and with that, JavaScript, .NET and Python programmers will feel right at home. Visual Studio Code can be used for Java (or Maven) projects as well. One reason to use it is the excellent [debug support that we have for Karate](https://twitter.com/KarateDSL/status/1167533484560142336).
It may be easier for you to use the Karate Maven archetype to create a skeleton project with one command. You can then skip the next few sections, as the pom.xml, recommended directory structure, sample test and [JUnit 5](#junit-5) runners - will be created for you. You can replace the values of com.mycompany and myproject as per your needs. This will create a folder called myproject (or whatever you set the name to).
Refer to this video for [getting started with the free IntelliJ Community Edition](https://youtu.be/W-af7Cd8cMc). It simplifies the above process, since you only need to install IntelliJ. For Eclipse, refer to the wiki on [IDE Support](https://github.com/intuit/karate/wiki/IDE-Support).

Support

Refer to the wiki - [IDE Support](https://github.com/intuit/karate/wiki/IDE-Support).

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.