Skip to main content

Karate DSL: Automating API and UI Testing

Karate DSL is an open-source test automation framework built on top of Java. It combines API test-automation, UI test-automation, mock services, and performance-testing into a single, unified framework. It's known for its simplicity, readability, and ease of use, making it a great choice for both developers and testers.

Key Features of Karate DSL

  • API Testing: Easily tests REST and GraphQL APIs with built-in support for JSON and XML.
  • UI Testing: Automates web browser interactions using Selenium-based driver management.
  • BDD Syntax: Uses a simple, behavior-driven development (BDD) syntax that's easy to understand and write. Features can be written in plain English, enhancing collaboration between technical and non-technical team members.
  • Data-Driven Testing: Supports data-driven testing with CSV, JSON, and other data sources.
  • Parallel Execution: Executes tests in parallel to reduce test execution time.
  • Mock Services: Creates mock services for simulating API endpoints during testing. Excellent for contract testing.
  • Reporting: Generates detailed test reports in HTML format.
  • Java Interoperability: Can be easily integrated with existing Java projects and libraries. Allows calling Java methods from Karate features.
  • No Coding Required (Mostly): Minimizes the need for Java coding, allowing you to focus on defining test scenarios.
  • Supports HTTP and HTTPS Protocol: Built in request and response management capabilities.
  • Native support for JSON and XML: Makes it easier to construct and parse data formats common in web services.
  • Embedded Expressions: Provides the ability to transform and retrieve data from complex responses.

Why Use Karate DSL?

  • Simplified Test Automation: Karate DSL simplifies test automation by providing a single framework for API, UI, and mock service testing.
  • Increased Test Coverage: Easy creation of comprehensive test suites.
  • Improved Collaboration: The BDD syntax makes it easier for developers, testers, and business stakeholders to collaborate on test development.
  • Faster Test Execution: Parallel test execution reduces test execution time.
  • Reduced Maintenance: The simple and readable syntax reduces the maintenance effort required for test scripts.
  • Low Learning Curve: If you know HTTP and JSON already, the learning curve is very shallow.

Getting Started with Karate DSL

  1. Add Karate Dependency: Include the Karate dependency in your project (e.g., Maven or Gradle).

    Maven:

    <dependency>
    <groupId>com.intuit.karate</groupId>
    <artifactId>karate-apache</artifactId>
    <version>1.4.1</version> <!-- Use the latest version -->
    <scope>test</scope>
    </dependency>

    Gradle:

    dependencies {
    testImplementation 'com.intuit.karate:karate-apache:1.4.1' // Use the latest version
    }

    Use karate-junit5 for JUnit 5 integrations. JUnit 4 is depreciated but supported.

  2. Create a Feature File: Create a feature file (e.g., example.feature) with the following content:

    Feature: Get User API Test
    Scenario: Get a specific user
    Given url 'https://reqres.in/api/users/2'
    When method get
    Then status 200
    And match response.data.first_name == 'Janet'
  3. Run the Test: Run the test feature using a JUnit runner. Create a KarateTest.java file, example using JUnit 5:

    import com.intuit.karate.junit5.Karate;
    import org.junit.jupiter.api.Test;

    class KarateTest {

    @Test
    Karate testUsers() {
    return Karate.run("example.feature");
    }

    }
  4. View the Report: Karate generates an HTML report after the test execution.

Karate DSL Syntax

Karate DSL uses a simple and readable syntax based on Gherkin, the same language used by Cucumber.

  • Feature: Defines a test feature.
  • Scenario: Defines a specific test scenario.
  • Given: Defines the initial state of the test.
  • When: Defines the action to be performed.
  • Then: Defines the expected outcome of the action.
  • And: Defines additional conditions or actions.
  • But: Defines negative conditions or actions.

API Testing with Karate

Karate DSL provides built-in support for API testing. Here's a more detailed example:

Feature: API Test Example

Background:
* url 'https://reqres.in/api'
* header Content-Type = 'application/json'

Scenario: Get a list of users
Given path '/users'
And param page = 2
When method GET
Then status 200
And match response.data[*].email contains '@reqres.in'

Scenario: Create a new user
Given path '/users'
And request { "name": "morpheus", "job": "leader" }
When method POST
Then status 201
And match response.name == 'morpheus'
And match response.job == 'leader'
And match response.id != null
And match response.createdAt != null

Scenario: Update an existing user
Given path '/users/2'
And request { "name": "morpheus updated", "job": "zion resident" }
When method PUT
Then status 200
And match response.name == 'morpheus updated'
And match response.job == 'zion resident'
And match response.updatedAt != null

Scenario: Delete a user
Given path '/users/2'
When method DELETE
Then status 204

Explanation:

  • url: Specifies the base URL of the API.
  • path: Appends a path to the base URL.
  • param: Adds a query parameter to the URL.
  • request: Sends a request body (JSON in this case).
  • method: Specifies the HTTP method (GET, POST, PUT, DELETE, etc.).
  • status: Verifies the HTTP status code.
  • match: Verifies the response body using powerful matching expressions. The matching expressions include contains, equals, startsWith, endsWith, etc. It's possible to use "#present" to ensure a field simply exists. Regular expressions are also supported.

UI Testing with Karate

Karate DSL can also be used for UI testing by using the karate-core dependency along with karate-driver.

Feature: UI Test Example

Scenario: Navigate to Google and search
Given driver 'chrome' # Requires chromedriver to be configured correctly
And url 'https://www.google.com'
And input('#APjFqb', 'Karate DSL')
And click("input[name='btnK']")
Then delay(5000) #Wait for 5 seconds.
And close()

Important Notes:

  • WebDriver Configuration: Karate UI automation relies on WebDriver (e.g., ChromeDriver, GeckoDriver). Make sure the appropriate WebDriver is installed and configured correctly. You can add the driver dependency in maven, and karate will automatically handle downloading and configuration.
  • Element Selectors: Karate uses CSS selectors or XPath expressions for identifying UI elements.
  • Actions: Karate provides actions like click, input, clear, submit, select, dragAndDrop, etc. for interacting with UI elements.
  • delay() can be used but should be avoided if possible with proper use of wait states, etc.

Data-Driven Testing

Karate supports data-driven testing, allowing you to run the same test scenario with different sets of data.

Feature: Data-Driven API Test

Scenario Outline: Create a user with different data
Given url 'https://reqres.in/api/users'
And request { "name": "<name>", "job": "<job>" }
When method POST
Then status 201
And match response.name == '<name>'
And match response.job == '<job>'

Examples:
| name | job |
| Morpheus | Leader |
| Neo | Savior |
| Trinity | Hacker |

Explanation:

  • Scenario Outline: Defines a test scenario that will be executed multiple times with different sets of data.
  • Examples: Defines a table of data that will be used for each execution of the scenario.
  • <name> and <job>: Placeholders that will be replaced with the values from the Examples table.

Mock Services

Karate DSL can also be used to create mock services for simulating API endpoints during testing. This is useful of contract testing your APIs.

Feature: Mock Service Example

Background:
* def mock =
"""
pathMatches('/hello') && methodIs('get')
* response { message: 'Hello, world!' }
"""

Scenario: Test with mock service
Given url 'http://localhost:8080'
And start mock mock
And path '/hello'
When method get
Then status 200
And match response.message == 'Hello, world!'
* stop mock

Explanation:

  • This example will obviously only work if no process is running on port 8080. Alternatively, it can use any ephemeral port.
  • start mock: Starts a mock service that will respond to requests that match the specified conditions.
  • pathMatches and methodIs: Define the conditions that must be met for the mock service to respond.
  • response: Defines the response that the mock service will return.
  • stop mock: Stops the mock service.

Reporting

Karate DSL generates detailed test reports in HTML format. The reports provide information about the test results, including the status of each scenario, the request and response details, and any errors that occurred.

Best Practices

  • Keep Feature Files Concise: Break down complex test scenarios into smaller, more manageable feature files.
  • Use Background Sections: Use the Background section for defining common setup steps that are executed before each scenario.
  • Parameterize Tests: Use data-driven testing to parameterize tests and run them with different sets of data.
  • Use Helper Functions: Create helper functions to encapsulate common logic and reuse them across multiple feature files. Consider using JavaScript or Java for more complex logic.
  • Write Clear and Concise Assertions: Write clear and concise assertions that accurately verify the expected outcome of the test.
  • Use Version Control: Store all your test scripts in a version control system (e.g., Git) to track changes and collaborate with other team members.

Integration with Java

You can call Java code directly from Karate features. This can be helpful for complex logic or calculations that are difficult to express in Karate DSL.

First, create a Java class:

public class MyJavaFunction {

public static String hello(String name) {
return "Hello, " + name + "!";
}
}

Then call it from your Karate feature:

Feature: Call Java Function
Scenario: Call a Java function
* def MyJavaFunction = Java.type('MyJavaFunction')
* def result = MyJavaFunction.hello('Karate')
Then match result == 'Hello, Karate!'

Alternatives to Karate DSL

  • Rest Assured: Popular Java library specifically for REST API testing.
  • Selenium: Widely used for UI testing, but requires more coding than Karate.
  • Cypress: JavaScript-based end-to-end testing framework, popular for modern web applications.
  • Playwright: A framework for reliable end-to-end testing for web apps. Supports multiple browsers and languages.
  • Postman: Widely used for exploring and testing APIs, but less suitable for automated testing.

Conclusion

Karate DSL is a versatile and powerful test automation framework that simplifies API, UI. It's BDD syntax, ease of use, and comprehensive features make it a great choice for organizations looking to improve their test automation efforts. By following the best practices outlined in this document, you can effectively use Karate DSL to create robust and maintainable test suites that ensure the quality of your applications.