Skip to main content

CORE SYNTAX

Feature Files Structure

Overview

Karate scripts use Gherkin format with three main sections: Feature, Background, and Scenario. Multiple scenarios can exist in a *.feature file, with at least one scenario required. The Background section is optional.

Basic File Structure

Feature: brief description of what is being tested
more lines of description if needed.

Background:
# this section is optional !
# steps here are executed before each Scenario in this file
# variables defined here will be 'global' to all scenarios
# and will be re-initialized before every scenario

Scenario: brief description of this scenario
# steps for this scenario

Scenario: a different scenario
# steps for this other scenario

Core Components

Feature Section

The Feature keyword defines the test file's purpose:

Feature: User Authentication API
This feature covers all authentication-related endpoints
including login, logout, and token validation scenarios.

Background Section

Executes before each scenario in the file:

Background:
* url 'https://api.example.com'
* def authToken = call read('get-auth-token.feature')
* header Authorization = 'Bearer ' + authToken

Important: Variables defined in Background are re-initialized before every Scenario. For one-time setup, use callonce.

Scenario Structure

Scenario: User login with valid credentials
Given path '/auth/login'
And request { username: 'testuser', password: 'password123' }
When method post
Then status 200
And match response.token == '#string'
And match response.expiresIn > 0

Scenario Outline for Data-Driven Tests

Scenario Outline: Test user creation with different data
Given path '/users'
And request { name: '<name>', email: '<email>' }
When method post
Then status <expectedStatus>

Examples:
| name | email | expectedStatus |
| John | john@example.com | 201 |
| Invalid | | 400 |
| Jane | jane@example.com | 201 |

Given-When-Then Convention

Karate provides HTTP-focused keywords while maintaining readable structure:

Purpose of Keywords

  • Given: Setup conditions and initial state
  • When: Execute the action being tested
  • Then: Verify results and assertions
  • And: Continue previous step type
  • *: Universal keyword for any step

Flexible Keyword Usage

Scenario: Keyword flexibility example
# Traditional approach
Given url 'https://api.example.com'
And path '/users'
When method get
Then status 200
And match response.length > 0

# Using * for clarity
* url 'https://api.example.com'
* path '/users'
* method get
* status 200
* match response.length > 0

The * symbol is perfect for Background sections or when traditional keywords don't provide semantic value.

Comments and Documentation

Lines starting with # are comments:

Feature: API Testing Examples

# This is a comment explaining the test setup
Background:
* url baseUrl # Base URL configuration

Scenario: Example with inline comments
# Setup test data
* def userId = 123

# Make the API call
Given path '/users/', userId
When method get

# Verify response
Then status 200
# Check user properties
And match response.id == userId

Variable Scope and Lifecycle

Background Variables

Background:
* def globalVar = 'available to all scenarios'
* def config = { timeout: 5000, retries: 3 }

Scenario: First test
* print globalVar # Will print 'available to all scenarios'
* assert config.timeout == 5000

Scenario: Second test
* print globalVar # Fresh copy from Background
* def localVar = 'only in this scenario'

Variable Re-initialization

Background variables are re-set before every scenario. If you expect one scenario to modify a variable for later scenarios, combine them into a single scenario instead.

Karate vs Traditional Cucumber

AspectTraditional CucumberKarate
Step DefinitionsRequired (Java code)✅ Built-in HTTP/JSON/XML steps
Layers to Maintain2 (Gherkin + Java)✅ 1 (Karate script only)
Natural Language✅ Reads like EnglishConcise DSL for web services
Feature ReuseNot supported✅ Call other feature files
Dynamic DataFixed Examples only✅ JSON/CSV as data source
Parallel ExecutionComplex setup✅ Built-in parallel scenarios
JavaScript EngineExternal dependency✅ Embedded JavaScript support

File Organization Best Practices

Directory Structure

src/test/java/
├── karate-config.js
├── logback-test.xml
└── examples/
├── users/
│ ├── user-crud.feature
│ ├── user-auth.feature
│ └── user-validation.feature
├── orders/
│ ├── order-lifecycle.feature
│ └── order-validation.feature
└── common/
├── setup.feature
└── utils.feature

Naming Conventions

  • Files: Use kebab-case (user-authentication.feature)
  • Scenarios: Descriptive names (User login with invalid credentials)
  • Variables: camelCase (authToken, userId)

Feature Organization

Feature: User Management API
Comprehensive testing of user-related endpoints
including CRUD operations and authentication.

Background:
* url baseUrl
* def utils = call read('classpath:common/utils.feature')

@smoke
Scenario: Create new user
# Smoke test for user creation

@regression
Scenario: Update existing user
# Full regression test

@negative
Scenario: Handle invalid user data
# Error handling validation

IDE Support and Integration

Karate inherits excellent IDE support from Gherkin:

  • IntelliJ IDEA: Full syntax highlighting, right-click to run scenarios
  • VS Code: Karate extension with debugging support
  • Eclipse: Cucumber plugin compatibility

Running Individual Scenarios

Feature: Quick Testing

@debug
Scenario: Debug this specific scenario
* print 'This can be run individually'
* def result = call read('some-feature.feature')

Right-click the scenario in your IDE to run it individually without executing the entire feature file.

Advanced Structure Patterns

Conditional Scenario Execution

@env=dev
Scenario: Development-only test
* print 'Only runs in dev environment'

@envnot=prod
Scenario: Never run in production
* print 'Skipped in production'

Setup and Cleanup Patterns

Feature: Order Processing

Background:
* def testData = call read('create-test-data.feature')

@setup
Scenario: Initialize test environment
* call read('setup-database.feature')

Scenario: Process order workflow
# Main test logic

@cleanup
Scenario: Clean up test data
* call read('cleanup-database.feature')

Performance Considerations

Parallel Execution Impact

# Scenarios run in parallel by default
Scenario: Can run in parallel
* def independent = true

@parallel=false
Scenario: Must run sequentially
* def requiresSequence = true

Anti-pattern: Avoid scenario dependencies. Each scenario should be independently executable.

Next Steps