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 everyScenario
. For one-time setup, usecallonce
.
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 forBackground
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
Aspect | Traditional Cucumber | Karate |
---|---|---|
Step Definitions | Required (Java code) | ✅ Built-in HTTP/JSON/XML steps |
Layers to Maintain | 2 (Gherkin + Java) | ✅ 1 (Karate script only) |
Natural Language | ✅ Reads like English | Concise DSL for web services |
Feature Reuse | Not supported | ✅ Call other feature files |
Dynamic Data | Fixed Examples only | ✅ JSON/CSV as data source |
Parallel Execution | Complex setup | ✅ Built-in parallel scenarios |
JavaScript Engine | External 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
- Learn about Variables and Assignment for data handling
- Explore Data Types and Formats for JSON/XML processing
- Understand Test Tags for scenario organization