All about Karate Framework


People think of automation to gradually reduce time-consuming repetitive and manual work. It is a known fact that automation testing reduces time, improves productivity, generates reports automatically, etc. Fundamentally one should have some level of expertise in coding to write automation test scripts and subsequently run it without any hassles, you need to have so many things handy while setting up a framework, say for instance you should have technical know-how of integrating necessary plugins, creating a proper folder structure for your code, selecting tools and IDE’s, etc. A newbie software tester with less coding knowledge will be overwhelmed with these setups and potentially neglect automation testing.

We’ve seen a lot of testers, QA engineers using Postman/Insomnia/Paw to test their REST API endpoints manually because they do not know how to automate them. Automating API testing is a more complex procedure, setting the initial process and running it successfully is often one of the most challenging parts of the process, one must be ready to face a series of challenges like parameter validation, a sequence of API calls, testing the parameter combination, etc.

Our engineers gave it a go with many API frameworks like RestAssured, SOAP UI, Katalon Studio and Karate. We have always been excited while working with Karate framework because Karate framework is promisingly a mature framework since API tests are written using plain text Gherkin style as it is built on top of Cucumber and is written in Java.

Why we recommend it

Java knowledge is not required and even non-programmers can write tests with ease ( it runs on JVM)

It supports JSON and XML including JsonPath and XPath expressions,

Re-use of payload-data and user-defined functions across tests is possible.

Simple latency assertions can be used to validate non-functional requirements like performance requirements. (for ex. it is used to measure the performance of the API when it is executed multiple times by measuring the response time)

How to Setup Karate framework

Let us see the step by step guide on setting up Karate framework

Start up your favorite IDE. (we are taking InteliJ IDEA in this example.)

Go to File> New> Maven Project and take the defaults on the first screen.

Under New Maven Project, click on Add Archetype

Enter the following info:

Archetype Group Id= com.intuit.karate
Archetype ArtifactId= karate-archetype
Archetype Version=0.9.4

Click Ok

It should find Karate-archetype. Click on Next.

Enter the ‘Groupid’ and ‘Artifactid’ for the project and click on Next.

Select the maven version and click on Next

Finish the Setup

Now the default karate project will be created with the ‘Feature and config files’.

Configuration

Karate-config.js

One has to check whether karate-config.js exist on the 'classpath'. A 'classpath' is a place where the important configuration files are expected to be in place by default, karate-config.js contains JavaScript function which will return a JSON object. The values and keys in this JSON object are available as script variables. The below sample JavaScript will tell you how one can get the value of the current 'environment' or 'profile', and then set up 'global' variables and helps you to understand the Karate configuration.

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;
}

A Global variable can be initialized in the config file which can be used in the test feature file. Also based on the environment we can set the global URL from the config file.

 package animals.cats;
import com.intuit.karate.junit4.Karate;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;

@RunWith(Karate.class)
public class CatsRunner {    
    @BeforeClass
    public static void before() {
        System.setProperty("karate.env", "e2e");
    }
}

Note: By default, the value of karate.env when you access it within karate-config.js - would be null.

Creating Tests

Testing the status code

Let's write a scenario that tests a GET endpoint and checks if it returns a 200 (OK) HTTP status code:

 Background:
    * url 'http://localhost:3000/api'
Scenario: get all users and then get the first user by id
    Given path 'dishes'
    When method get
    Then status 200 

Here we have the common URL in the Background, in the given path ‘dishes’ will be the route to the URL. This works obviously with all possible HTTP status codes.

Testing the Response

Let's write another scenario that tests that the REST endpoint returns a specific response:

Scenario: Testing the exact response of a GET endpoint
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
And match $ == {id:"1234",name:"John Smith"}

The match operation is used for the validation where ‘$' represents the response. So the above scenario will check that the response exactly matches ‘{id:”1234″,name:”John Smith”}'.

We can also check specifically for the value of the id field:

And match $.id == "1234"

The match operation can also be used to check if the response contains certain fields. This is helpful when only certain fields need to be checked with values or when not all response fields are known:

Scenario: Testing that GET response contains specific field
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
And match $ contains {id:"1234"}

Validating Response Values with Markers:

At times, when we don't know the exact value that is returned, we can still validate the value using markers — placeholders for matching fields in the response.

All about Karate Framework

Ex.
Scenario: Test GET request exact response
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
And match $ == {id:"#notnull",name:"John Smith"}
And match $ contains {id:”#notpresent”}

Testing a POST Endpoint with a Request Body

Let's look at a final scenario that tests a POST endpoint and takes a request body:

Scenario: Testing a POST endpoint with request body
Given url 'http://localhost:8097/user/create'
And request { id: '1234' , name: 'John Smith'}
When method POST
Then status 200
And match $ contains {id:"#notnull"}

Schema Validation:

Karate provides a simpler, user-friendly and more powerful response validation using Json as a variable to validate the structure of a given payload.

* 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'

We have been using the Karate framework for quite some time now and this framework comes with a very rich set of useful features that enables you to perform Automated API Testing very easily and quickly. It eases the testing process by allowing script developers or testers without any programming knowledge to script the sequences of HTTP calls. We believe that through this tutorial you have gained a lot of useful insights and got a basic understanding of Karate‘s features. Please feel free to reach out for your API testing needs, we are glad to help.


Leave a Reply

Your email address will not be published. Required fields are marked *