logo logo

Nailing Down API Testing With Karate Framework

API testing, be it REST, SOAP, JSON, XML or GraphQL, can be tricky – both from perspectives of the testing code itself and from maintaining it up to date as it evolves over time. However, by using Karate Framework you can overcome these struggles! Karate Framework helps get rid of the boilerplate code which is involved in performing the requests and asserting the response contents. In addition, it provides a descriptive language based on Cucumber that allows tests to be easily written and understood even by non-programmers.

In order to demonstrate a bit of the framework, we need first an accessible API. Let’s use a playground project from Best Buy. The setup is fairly easy to have it up and running in a few minutes. After the playground API is running, it is time to get started with the API testing.

Let’s use a Maven archetype to boost the project quickly.
Our development environment will be Intellij Idea CE with Cucumber Plugin, Java 8 and Maven 3. 

Create a folder to host the test project and run the command below:

mvn archetype:generate \
-DarchetypeGroupId=com.intuit.karate \
-DarchetypeArtifactId=karate-archetype \
-DarchetypeVersion=0.5.0 \
-DgroupId=io.testproject \
-DartifactId=api-testing

At this point, you have the project structure ready to start writing the tests. The archetype comes with some testing samples, but we will write our own. Let’s create one package folder and name it features under src/test/java. This is where all the feature files will reside.

In order to run tests on feature files, you will need one class at the root of our features folder like the one below:

APITest.java
package features;

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

@RunWith(Karate.class)
public class APITest { }

This class is needed so the Maven test phase picks up the test files and runs all the tests recursively on the sub-folders. Now we can proceed and create our first feature file. Let’s create a file called products.feature under src/test/java/features/products.

This is how your project structure should look like:

API testing

 

 

 

 

 

 

 

 

We can add the first test as below:

products.feature
Feature: Verify that products are properly returned by the API

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

  Scenario: Products are returned on GET

    Given   path 'products'
     When method get
     Then status 200

This is a very basic test: it just verifies that after we perform a GET on the /products endpoint, we should receive an HTTP code 200 that implies a successful call. After we are finished we can call mvn test and see the test output. The feature file will be executed, with all the scenarios and steps on it.

Let’s add another scenario to check more advanced tests:

products.feature
#existing content of products.feature

  Scenario: Specific product has minimum required data to be displayed

    Given  path 'products/9132294'
    When method get
    Then status 200
     And  match $ == { price: #notnull, description: #notnull, image: #notnull  }

Now we are navigating to a specific product and verifying it contains the minimum information to be displayed in the website. We need to check whether it has price, description and image. Let’s run the mvn test again.

We can see our first test failure. The == operator tells the framework to expect exactly the 3 fields in question, but as the response has several others, it fails. In order to verify the response has at least the 3 fields we expect, we need to correct it by using the contains operator:

products.feature
#existing content of products.feature

  Scenario: Specific product has minimum required data to be displayed

    Given  path 'products/9132294'
    When method get
    Then status 200
     And  match $ contains { price: #notnull, description: #notnull, image: #notnull  }

And now the test works as expected. Karate implements JsonPath expressions to traverse on the response fields, which makes it easier to interact. We can add one small example to our last feature:

products.feature
#existing content of products.feature

  Scenario: Specific product has minimum required data to be displayed

    Given  path 'products/9132294'
    When method get
    Then status 200
     And  match $ contains { price: #notnull, description: #notnull, image: #notnull  }
     And  match $.categories contains { id: #notnull, name: #notnull, createdAt: #notnull, updatedAt: #notnull }

That’s it, we are now able to navigate to the categories array and evaluate its content without writing complicated matchers or delicate string manipulations.

This tutorial highlights some of the core features of Karate Framework that will allow you to create a bullet-proof API Testing with very little setup, a learning curve and deliver robust and easy-to-maintain tests. For a more comprehensive feature list, please check Karate project in GithubThe code found on this sample project can be found at my Github.

What do you think of API testing with Karate Framework?  You are welcome to leave your thoughts and questions in the comment section below.  Happy Testing!  😎 

About the author

Neill Lima

Software Development Engineer in Test at N26

Comments

25 8 comments
  • Sam September 13, 2018, 2:23 pm

    Hi Neil,

    Great Tool and very well explained.
    I am trying to configure the project using Karate API in my eclipse JAVA EE for Developer and IntelliJ Community edition. But there in feature file steps are looking for glue code. Could you please help me resolve the issue.

    Thanks,
    Sangamesh

  • jo January 4, 2019, 5:26 am

    Hi Neill,
    I want help for validating API response using karate framework.
    I have API’s which are “independent” on each other.
    I have POST method along with request parameters. when I hit that particular API got the response with different parameters (no single match from request parameter and response parameter).
    Now I want to validate response parameter value. how to do it.
    I tried using reponse.contains but it always “Pass” the result.

    example : request: “method” post
    school name: “abcd”
    register date : “1:10:2010″

    Response:
    Principle name : ” pqrs”
    Principle Email id “[email protected]

    now I want to validate that “principle name ” should not be null

    I have implemented like this but it it doesn’t work

    Feature: School info

    Background:
    * url baseUrl

    Scenario: check Principles info

    Given path ‘School info’
    And request {school name: “abcd” ,register date : “1:10:2010”}
    When method post
    Then status 200
    And match response.response contains {“type”: “Success”,”code”:20000}
    And match response.principle list[*] { “Principle name”: “#notnull”}

  • shirishganjewar May 23, 2019, 4:47 am

    Hi Neill,

    {Sorry for long post}

    if possible share your comment on my below query.
    I am executing the Karate Suite through Jenkins job which is maven based. While execution the job ends it with comment like
    [INFO] — maven-surefire-plugin:2.12.4:test (default-test) @ Karate_Digital —
    [INFO] Skipping execution of surefire because it has already been run for this configuration
    [INFO] ————————————————————————
    [INFO] BUILD SUCCESS

    I am clueless as not able to execute my suite through Maven in my IDE too with the similar message.

    My POM looks like below

    4.0.0

    Karate_Digital
    Karate_Digital
    0.0.1-SNAPSHOT
    jar

    UTF-8
    1.8
    3.6.0
    0.9.1

    com.intuit.karate
    karate-jersey
    ${karate.version}
    test

    com.intuit.karate
    karate-junit4
    ${karate.version}
    test

    net.masterthought
    cucumber-reporting
    4.5.1

    <!– src/test/java
    **/*.java
    –>

    org.apache.maven.plugins
    maven-compiler-plugin
    ${maven.compiler.version}

    Problem Statement
    true

    report-only

    UTF-8
    ${java.version}
    ${java.version}
    -Werror
    digital_statement_automation_team/src/test/java/com/barclaycard/qe/runner

    **/*Runner_API.java

  • uditchoudhary June 4, 2019, 1:44 am

    Hi Neill,
    I have an existing automation framework with Java Junit appium and gradle to test mobile app.
    There are some user scenarios where I need to make few changes in customer profiles. I want to reset the test data after making that change, so I am thinking of using Karate to make those api calls instead of automating the UI part which is time consuming.

    Can you please assist how I can integrate it with my existing Appium automation framework?

    Cheers
    Udit Choudhary

  • Bhuvnesh Sainani June 25, 2021, 5:32 am

    Anyone has tried NTLM authentication ?? if someone can help

  • Rachit Zambre December 7, 2022, 7:30 am

    Great tool and well explained

Leave a Reply

FacebookLinkedInTwitterEmail