Karate Framework – Tutorial to Start Api & UI Automation

Karate Framework Overview

Karate is an open-source, Java-based testing framework primarily used to test web services and APIs. It provides a unified framework for API testing, UI automation, and performance testing.
Karate stands out from other testing frameworks because it combines the capabilities of a test-automation framework and a domain-specific language (DSL) for testing HTTP-based APIs and services.

Here is an overview of the key features and components of the Karate framework:

  1. BDD Syntax: Karate uses a Behavior-Driven Development (BDD) syntax that allows you to write test scenarios in a human-readable format. This syntax makes it easier for technical and non-technical team members to collaborate and understand the tests.
  2. API Testing: Karate excels in API testing and provides built-in support for testing REST, SOAP, and GraphQL APIs. It has features for making HTTP requests, validating responses, handling headers, cookies, and authentication, and performing complex data-driven testing.
  3. Test Doubles: Karate allows you to create test doubles (mocks or stubs) for external dependencies, enabling you to test your system in isolation. This is particularly useful when you need to simulate responses from downstream services that are not available during testing.
  4. UI Automation: While Karate is primarily designed for API testing, it also includes limited support for UI automation. It provides a set of utilities that can interact with web pages and perform actions such as form submissions, clicks, and assertions.
  5. Data-Driven Testing: Karate supports data-driven testing by allowing you to define test data in tabular form (e.g., CSV, Excel), JSON, or JavaScript objects. This enables you to execute the same test scenario with different data sets, making your tests more comprehensive and reusable.
  6. Reporting: Karate generates detailed HTML reports that include information about the executed tests, their status (pass/fail), and any failures or errors encountered. These reports can be shared with stakeholders for better visibility and analysis of the test results.
  7. Integrations: Karate can be easily integrated with popular development and continuous integration tools such as Maven, Gradle, Jenkins, and Cucumber. It also supports running tests in parallel, which reduces test execution time.
  8. Extensibility: Karate provides an extensible architecture, allowing you to write custom Java code and integrate it seamlessly into your test scenarios. This feature enables you to incorporate complex business logic or interact with external systems during your tests.

Karate Comparision with Rest Assured:

Before directly jumping into Karate it is very important to know why karate has the upper hand on rest-assured. Both tools are good. But when we have multiple choices then below is the comparison that can help you to decide the correct tool for your need.

FeatureKarateRest Assured
API TestingSupports API testing using the Gherkin syntaxSupports API testing with a fluent, Java-based approach
Request SpecificationDefine requests in feature files using a BDD syntaxDefine requests programmatically using Java
Response ValidationBuilt-in support for JSON and XML response validationJSON response validation using Hamcrest or custom matchers
Test ExecutionRun tests as feature files or via JUnit integrationExecute tests using JUnit or TestNG frameworks
Test Data ManagementBuilt-in support for reading data from JSON, CSV, and XML filesRequires custom code for data management
ReportingBuilt-in HTML reports with detailed test resultsSupports custom reporting frameworks like Extent Reports
Parallel ExecutionSupports parallel test execution out of the boxCan be achieved using TestNG or custom implementation
MockingBuilt-in support for mocking API responsesRequires additional libraries like WireMock
AuthenticationSupports basic, digest, and OAuth2 authenticationSupports various authentication mechanisms
IntegrationsProvides integrations with CI/CD tools like Jenkins, BambooIntegrates with CI/CD tools like Jenkins, TeamCity, etc.
Community SupportActive community with good documentation and supportStrong community support with extensive resources
Learning CurveEasy to learn with a simple syntax and comprehensive docsSteeper learning curve due to Java programming requirement

These are the major points. Details comparison can be found here. Click here

Karate Vs Cucumber:

One of the comparisons you need is between cucumber and karate. please find the detailed comparison below:

FeatureKarateCucumber
PurposeAPI testing and automation tool with BDD-style syntaxBehaviour-driven development (BDD) framework
LanguageBuilt-in support for API testing in a dedicated languageSupports multiple programming languages (e.g., Java, Ruby)
SyntaxKarate-specific syntax using Gherkin for API testingGherkin syntax for defining behaviour and acceptance criteria
Data-Driven TestingBuilt-in support for data-driven testingSupports data-driven testing using scenario outlines
Request SpecificationDefine requests and scenarios using Karate-specific syntaxDefine features and scenarios using Gherkin syntax
Step DefinitionsStep definitions are written in Karate-specific syntaxStep definitions are written in a programming language
Response ValidationBuilt-in support for JSON and XML response validationRequires custom code or libraries for response validation
Test ExecutionRun tests as feature files or via JUnit integrationExecute tests using Cucumber runners or integrations
ReportingBuilt-in HTML reports with detailed test resultsSupports custom reporting frameworks and plugins
Parallel ExecutionSupports parallel test execution out of the boxCan be achieved using test runners or plugins
Scenario OutlineSupports scenario outline functionality for data-driven testsSupports scenario outline functionality for data-driven tests
TaggingSupports tagging features and scenarios for test organizationSupports tagging features and scenarios for test organization
BackgroundSupports a background section for common steps or setupSupports a background section for common steps or setup
IntegrationsProvides integrations with CI/CD tools like Jenkins, BambooIntegrates with CI/CD tools like Jenkins, TeamCity, etc.
Community SupportActive community with good documentation and supportStrong community support with extensive resources
Learning CurveEasy to learn with a simple syntax and comprehensive docsModerate learning curve due to various language options

Karate Framework Setup

To set up the karate framework you can choose any build tool: Maven or Gradle. I will use Intellij idea IDE for this tutorial, You can choose any IDE as per your comfort.

Tools Required:

1. IDE ( IntelliJ IDEA, Eclipse, Visual Studio Code)

Download the IDE from here (IntelliJ IDEA, Eclipse, Visual Studio Code) if not installed.

2. Build Tool ( Maven or Gradle)

Maven

<dependency>
    <groupId>com.intuit.karate</groupId>
    <artifactId>karate-junit5</artifactId>
    <version>1.4.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.intuit.karate</groupId>
    <artifactId>karate-core</artifactId>
    <version>1.4.0</version>
</dependency>

Gradle

implementation 'com.intuit.karate:karate-core:1.4.0'
testCompile 'com.intuit.karate:karate-junit5:1.4.0'

3. Java ( We are using )

In order to install Java in your system if not installed then go through this article once to install Java in your system.

If you are a Java developer – Karate requires at least Java 11 and then either MavenGradle, or a Java IDE that embeds either to be installed. Note that Karate works fine on OpenJDK.

If you don’t want to use Java, the Karate extension for Visual Studio Code is recommended, and JavaScript, .NET, Ruby and Python programmers will feel right at home.

Quickstart

One way is that you can manually create the project and add the dependencies by manually. But this is very tedious to do. To make it quick 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 runners – will be created for you.

In the below command, You can replace the values of com.mycompany and myproject as per your needs.

mvn archetype:generate \
-DarchetypeGroupId=com.intuit.karate \
-DarchetypeArtifactId=karate-archetype \
-DarchetypeVersion=1.4.0 \
-DgroupId=com.qatestauto \
-DartifactId=KarateProject
Karate framework structure, karate default framework

The above project will be created by default.

Folder Structure of Karate Framework

Feature files: Karate also use the *.feature extension which is used by Cucumber. So it is similar to cucumber. To organise the code you can simply follow the Java package convention.

1. Root Folder:

This is the main folder for your Karate project. It typically contains the project configuration files and other high-level files. Examples of files you might find here include:

  • pom.xml (if using Maven) or build.gradle (if using Gradle) for managing dependencies.
  • karate-config.js for global configuration and setup.
  • karate.env for environment-specific variables.

2. src Folder:

This folder contains the main source code for your Karate tests. It often follows a structure similar to a typical Java project.

Example sub-folders within src include:

  • main: This folder typically contains reusable utility functions or custom Java classes that you may use in your Karate tests.
  • test: This is where your actual Karate test files reside.
  • features: This folder holds the feature files that define your API tests using the Gherkin syntax.
  • java: You can place any custom Java code here, which can be used in your Karate tests if necessary.

3. target or build Folder:

This folder is usually generated by build tools like Maven or Gradle. It contains the compiled output and any generated artifacts, such as test reports, code coverage reports, or executable files.
It’s generally recommended to add this folder to the project’s .gitignore file to exclude it from version control.

Additional Folders (Optional):
Depending on your project’s requirements, you may have additional folders to organize specific types of files or resources.

Examples of additional folders include:

  • data: This folder can contain test data files in various formats like JSON, XML, or CSV.
  • reports: You can store generated test reports or logs in this folder.
  • resources: This folder may hold additional resources, such as property files, configuration files, or mock data.

Remember that the above folder structure is a general recommendation, and you can customize it according to your project’s specific needs.

Write Karate API Tests

Steps:

1. Create a feature file

Create a new feature file using the “.feature” extension. Define the feature and scenario(s) you want to test. For example:

Feature: Booking feature

  Scenario: Create booking and get booking id
    Given url baseUrl
    * path '/booking'
    * header Content-Type = 'application/json'
    * header Accept = 'application/json'
    * def bookingRequest = read('createBookingPayload.json')
    * request bookingRequest
    When method post
    Then status 200
    * print response
    * print response.bookingid

Karate pre-defined keywords used:

  • url: This is used to define URL. For Example: Given url ‘https://myhost.com/v1/cats’
  • path: REST-style path parameters. These can be expressions that will be evaluated. Comma-delimited values are supported which can be more convenient and takes care of URL-encoding and appending ‘/’ between path segments as needed.
    For example:
    path with an appended slash
    Given path ‘documents’, ‘/’
  • header: This defines the HTTP headers.
  • def: Used to define the Karate scenario variables
  • request: This is used to define the body
  • method: Used to define the HTTP method. For example: get, put and post etc.
  • status: This is used to define the expected HTTP Status code of the API call. For example 200, 201, 403, 401 etc.
  • response: This is the variable to hold the response sent by API call.
  • read(): Used to read the file from the framework. For Example to read JSON file: Given def data = read(‘sample.json’)
Karate api test
first api test

2. Execute the Test

To execute the test suite create the runner file as below:

package examples.users;

import com.intuit.karate.junit5.Karate;

class UsersRunner {
    
    @Karate.Test
    Karate testUsers() {
        return Karate.run("users").relativeTo(getClass());
    }

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

    @Karate.Test
    Karate testSystemProperty() {
        return Karate.run("classpath:examples/users/users.feature")
                .tags("@second")
                .karateEnv("e2e")
                .systemProperty("key", "value");
    }
}
karate api tests, karate api execution ests

3. Parallel Execution

To execute tests in parallel using Junit5, we need to add parallel() at the end and mention the thread count as a parameter.

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

class KarateTestParallel {

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

4. Report

When you use the JUnit runner – after the execution of each feature, an HTML report is output to the karate-report folder

karate-summary.html: This contains the summary of all the scenario execution as mentioned below.
This will contain the steps information and print keyword information too.

karate.log: This file contains the karate execution logs.

karate-tags.html: This is a karate tag-wise report.

karate-timeline.html: This will show the timeline of scenario execution. This is useful for visually verifying or troubleshooting the effectiveness of the test run. For example, we can see the report below:

Karate Report will be looks like as below:

karate-config.js

The configuration of a config.js file for a Karate project can vary depending on the specific requirements and setup of your project. This is a javascript-based configuration. However, I can provide you with an example of a basic config.js file configuration that you can use as a starting point. Here’s an example:

function fn() {
  var config = {
    baseUrl: 'https://restful-booker.herokuapp.com', // Base URL of your API

    // Common headers to be sent with each request
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer <your_token>'
    },

    // Global variables that can be used across scenarios
    globalVariables: {
      accessToken: null,
      userId: null
    },

    // Function to set access token globally
    setAccessToken: function (token) {
      config.globalVariables.accessToken = token;
      config.headers.Authorization = 'Bearer ' + token;
    },

    // Function to set user ID globally
    setUserId: function (userId) {
      config.globalVariables.userId = userId;
    },

    // Karate-specific configurations
    karateConfig: {
      // Timeout for each request in milliseconds
      readTimeout: 30000,

      // Timeout for establishing a connection in milliseconds
      connectTimeout: 5000,

      // Retry configuration
      retry: {
        count: 3,
        interval: 2000
      }
    }
  };

  return config;
}

In this example, the config of the object contains various properties:

  • baseUrl: The base URL of your API. Replace 'https://restful-booker.herokuapp.com' with the actual base URL, you are using.
  • headers: Common headers that will be sent with each request. You can modify or add headers as per your API requirements.
  • globalVariables: Global variables that can be used across scenarios. You can add or modify variables based on your needs.
  • setAccessToken and setUserId: Functions to set the access token and user ID globally. You can customize these functions to match your authentication mechanism.
  • karateConfig: Karate-specific configurations such as timeouts and retry settings. You can adjust these values based on your project requirements.

You can save this configuration in a config.js file in your Karate project and use it within your Karate feature files by calling karate.configure(‘config.js’).

Write First UI Test

Create register.feature file

Create the ui package and inside create the register.feature file. And the test is as below:

Feature: Register into online shopping portal

  Background: Click on Sign in button
    Given driver automationPracticeAppUrl
    * waitFor('a[class=login]').click()

  @Register
  Scenario: Register into online shopping portal
    Given def email = 'test589@email.com'
    * input('#email_create', email)
    * click('#SubmitCreate')
    * input('#customer_firstname', 'FirstName')
    * input('#customer_lastname', 'LastName')
    * def password = 'password'
    * input('#passwd', 'password')
    * input('#firstname', password)
    * input('#address1', 'Street number 78, New jersy USA')
    * input('#city', 'New York')
    * select('select[id=id_state]', 4)
    * input('#postcode', '13549')
    * select('select[id=id_country]', 'United States')
    * input('#phone_mobile', '912791827')
    * input('#alias', 'HomeAddress')
    * click('#submitAccount')
    Then match text('.info-account') == 'Welcome to your account. Here you can manage all of your personal information and orders.'

As you can see we can use different keywords for UI tests for example:

  • input: to send input to text field example: Then input(‘#id’, ’email’)
  • select: To perform operations on the dropdown
  • click: To click on the web element

Create SignIn Feature

Create another file signin.feature in the same package.

@UI
Feature: Login into online shopping portal
  
  @SignIn @Positive
  Scenario: Verify that user can login with valid credentials
    * call read('register.feature@Register')
    * print email
    * print password
    * click('.logout')
    * input('#email', email)
    * input('#passwd', password)
    * click('#SubmitLogin')
    Then match text('.info-account') == 'Welcome to your account. Here you can manage all of your personal information and orders.'

  @SignIn @Negative
  Scenario: Verify that user can't login with invalid credentials
    Given driver automationPracticeAppUrl
    * waitFor('a[class=login]').click()
    * input('#email', 'test5821291289@email.com')
    * input('#passwd', 'password')
    * click('#SubmitLogin')
    Then match text('.alert.alert-danger p') == 'There is 1 error'
    * match text('.alert.alert-danger ol li') == 'Authentication failed.'

In the above two examples, The first feature has one scenario to register the user. In the second feature file, we have two scenarios one positive and one negative for the login feature.

Calling another *.feature file

Karate has a special way to call the feature file. We can call another feature file scenario using the below piece of code as a precondition for another scenario.

call read('register.feature@Register')

Execution and reports will be the same as above.

Leave a Comment