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:
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
Feature | Karate | Rest Assured |
---|---|---|
API Testing | Supports API testing using the Gherkin syntax | Supports API testing with a fluent, Java-based approach |
Request Specification | Define requests in feature files using a BDD syntax | Define requests programmatically using Java |
Response Validation | Built-in support for JSON and XML response validation | JSON response validation using Hamcrest or custom matchers |
Test Execution | Run tests as feature files or via JUnit integration | Execute tests using JUnit or TestNG frameworks |
Test Data Management | Built-in support for reading data from JSON, CSV, and XML files | Requires custom code for data management |
Reporting | Built-in HTML reports with detailed test results | Supports custom reporting frameworks like Extent Reports |
Parallel Execution | Supports parallel test execution out of the box | Can be achieved using TestNG or custom implementation |
Mocking | Built-in support for mocking API responses | Requires additional libraries like WireMock |
Authentication | Supports basic, digest, and OAuth2 authentication | Supports various authentication mechanisms |
Integrations | Provides integrations with CI/CD tools like Jenkins, Bamboo | Integrates with CI/CD tools like Jenkins, TeamCity, etc. |
Community Support | Active community with good documentation and support | Strong community support with extensive resources |
Learning Curve | Easy to learn with a simple syntax and comprehensive docs | Steeper 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:
Feature | Karate | Cucumber |
---|---|---|
Purpose | API testing and automation tool with BDD-style syntax | Behaviour-driven development (BDD) framework |
Language | Built-in support for API testing in a dedicated language | Supports multiple programming languages (e.g., Java, Ruby) |
Syntax | Karate-specific syntax using Gherkin for API testing | Gherkin syntax for defining behaviour and acceptance criteria |
Data-Driven Testing | Built-in support for data-driven testing | Supports data-driven testing using scenario outlines |
Request Specification | Define requests and scenarios using Karate-specific syntax | Define features and scenarios using Gherkin syntax |
Step Definitions | Step definitions are written in Karate-specific syntax | Step definitions are written in a programming language |
Response Validation | Built-in support for JSON and XML response validation | Requires custom code or libraries for response validation |
Test Execution | Run tests as feature files or via JUnit integration | Execute tests using Cucumber runners or integrations |
Reporting | Built-in HTML reports with detailed test results | Supports custom reporting frameworks and plugins |
Parallel Execution | Supports parallel test execution out of the box | Can be achieved using test runners or plugins |
Scenario Outline | Supports scenario outline functionality for data-driven tests | Supports scenario outline functionality for data-driven tests |
Tagging | Supports tagging features and scenarios for test organization | Supports tagging features and scenarios for test organization |
Background | Supports a background section for common steps or setup | Supports a background section for common steps or setup |
Integrations | Provides integrations with CI/CD tools like Jenkins, Bamboo | Integrates with CI/CD tools like Jenkins, TeamCity, etc. |
Community Support | Active community with good documentation and support | Strong community support with extensive resources |
Learning Curve | Easy to learn with a simple syntax and comprehensive docs | Moderate 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 Maven, Gradle, 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
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) orbuild.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’)
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");
}
}
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.