CORE SYNTAX
Actions
Load files, evaluate JavaScript dynamically, and embed HTML documentation into test reports using Karate's built-in action keywords.
On This Page
- read() - Load files with auto-conversion (test data, schemas, features)
- karate.readAsString() - Load files as raw text (CSV uploads, templates)
- doc - Embed HTML in reports (custom documentation, visualization)
- eval - Execute JavaScript dynamically (use sparingly)
Reading Files
Karate's read() function loads files from your project with automatic type conversion. Use it to reuse test data, schemas, and utility functions across your test suite.
Loading Test Data
Read JSON and XML files for request payloads and validation:
Feature: Loading test data
Scenario: Read JSON and XML files
# JSON files auto-convert to objects
* def userData = read('user-data.json')
* def userArray = read('users-list.json')
# XML files auto-convert to XML objects
* def configXml = read('config.xml')
* def orderXml = read('sample-order.xml')
Loading Tabular Data
Read CSV and YAML files as structured data:
Feature: Loading tabular data
Scenario: Read CSV and YAML files
# CSV files become JSON arrays (header row required)
* def users = read('users.csv')
# YAML files become JSON objects
* def config = read('config.yaml')
Loading Reusable Code
Read JavaScript files to reuse functions across tests:
Feature: Loading reusable code
Scenario: Read JavaScript functions
# JavaScript files evaluate to functions
* def utils = read('helpers.js')
* def result = utils.processData({ name: 'John' })
# Call JavaScript functions directly
* def transform = read('data-transform.js')
* def transformed = transform(userData)
Loading Templates and Text
Read text files for templates and queries:
Feature: Loading templates
Scenario: Read text files
# Text files load as strings
* def emailTemplate = read('email-template.txt')
* def sqlQuery = read('user-query.sql')
* def graphqlQuery = read('user-query.graphql')
Loading Binary Files
Read binary files for upload operations:
Feature: Loading binary files
Scenario: Read binary files for uploads
# Binary files load as byte arrays
* def pdfFile = read('document.pdf')
* def imageFile = read('logo.png')
# Use in multipart uploads
Given url baseUrl
And path 'upload'
And multipart file document = { read: 'document.pdf' }
When method post
Then status 200
Path Prefixes
Control where files are loaded from using path prefixes:
| Prefix | Description | Example | Best For |
|---|---|---|---|
| classpath: | From classpath root | classpath:auth/login.feature | Shared, reusable resources |
| this: | Relative to current feature | this:helper.feature | Called features |
| file: | Absolute file paths | file:/tmp/output.json | Development only |
| (none) | Relative to feature file | user-data.json | Feature-local resources |
Use classpath: prefix for shared resources that are reused across features, and relative paths for feature-local files.
Feature: Using path prefixes
Scenario: Load files from different locations
# Shared resources (recommended for reuse)
* def commonAuth = read('classpath:auth/login.feature')
* def sharedData = read('classpath:common/test-data.json')
# Feature-local files
* def localData = read('user-data.json')
* def schema = read('user-schema.json')
# Called features (ensures correct relative paths)
* def helper = read('this:helper-scenario.feature')
# Environment-specific files (dynamic loading)
* def env = karate.env || 'dev'
* def config = read('classpath:config/' + env + '.json')
Read File As String
Bypass Auto-Conversion
Use karate.readAsString() to read files as raw text:
Feature: Read as string operations
Scenario: Read files without auto-conversion
# Read JSON as string (no parsing)
* def jsonString = karate.readAsString('user-data.json')
* def parsedLater = JSON.parse(jsonString)
# Read CSV as raw text
* def csvString = karate.readAsString('data.csv')
* def lines = csvString.split('\\n')
# Read binary files as strings (for specific use cases)
* def configText = karate.readAsString('config.txt')
# Process template files
* def template = karate.readAsString('email-template.html')
* def processed = template.replace('{{name}}', 'John').replace('{{date}}', new Date().toDateString())
* assert jsonString.startsWith('{')
* assert lines.length > 1
* assert processed.includes('John')
Use Cases for String Reading
Feature: String reading use cases
Scenario: When to read as string
# For custom parsing logic
* def rawData = karate.readAsString('custom-format.txt')
* def customParsed = processCustomFormat(rawData)
# For template processing
* def htmlTemplate = karate.readAsString('report-template.html')
* def report = htmlTemplate.replace('{{title}}', 'Test Report').replace('{{results}}', testResults)
# For preserving exact formatting
* def query = karate.readAsString('complex-query.sql')
* def formattedQuery = query.replace('{{table}}', 'users_' + env)
# For GraphQL queries (treated as text)
* def graphqlQuery = karate.readAsString('user-query.graphql')
* def variables = { userId: 123 }
Given path 'graphql'
And request { query: graphqlQuery, variables: variables }
When method post
Then status 200
doc - HTML Templating
Use the doc keyword to embed custom HTML into Karate test reports.
Insert HTML into Reports
Feature: HTML documentation in reports
Scenario: Generate documentation with doc
# Load and process data
* url 'https://jsonplaceholder.typicode.com/users'
* method get
* status 200
# Create documentation for the API response
* doc { read: 'users-table.html' }
# Custom HTML with dynamic content
* def reportTime = new Date().toISOString()
* def userCount = response.length
* doc
"""
<div style="border: 1px solid #ccc; padding: 10px; margin: 10px 0;">
<h3>API Test Results Summary</h3>
<p><strong>Endpoint:</strong> /users</p>
<p><strong>Users Retrieved:</strong> """ + userCount + """</p>
<p><strong>Test Time:</strong> """ + reportTime + """</p>
<p><strong>Response Time:</strong> """ + responseTime + """ms</p>
<p style="color: green;"><strong>Status:</strong> Success</p>
</div>
"""
* print 'Documentation added to HTML report'
HTML Templates with Variables
Feature: HTML templates
Scenario: Use external HTML templates
# Load test data
* def users = [{ id: 1, name: 'John Doe', email: 'john@test.com', active: true }, { id: 2, name: 'Jane Smith', email: 'jane@test.com', active: false }]
# Template file uses Thymeleaf syntax to access Karate variables
# All variables defined in the scenario are available in the template
* doc { read: 'users-table.html' }
* print 'Users table added to report'
eval - Dynamic Execution
⚠️ Use Sparingly: The eval keyword executes JavaScript dynamically and should be used only as a last resort. Tests should be deterministic - avoid conditional logic when possible.
When to Use eval
Use eval only for:
- One-off logic where a reusable function is overkill
- Conditional logic (see Conditional Logic)
- Actions where you don't need to save the result
- Dynamic variable assignment
Note: You can omit the eval keyword for cleaner code.
Basic Usage
Feature: Using eval
Scenario: Evaluate JavaScript expressions
# With eval keyword
* eval myJavaScriptFunction()
# Without eval (cleaner)
* myJavaScriptFunction()
# Conditional assignment
* def zone = 'zone1'
* if (zone == 'zone1') karate.set('temp', 'after')
* match temp == 'after'
# Execute code without saving result
* eval console.log('Test completed')
Dynamic Configuration
Feature: Dynamic configuration with eval
Scenario: Build configuration based on environment
* def environment = 'staging'
# Build config dynamically
* eval
"""
var config = {
baseUrl: environment === 'prod' ? 'https://api.example.com' : 'https://staging-api.example.com',
timeout: environment === 'prod' ? 30000 : 10000,
debug: environment !== 'prod'
};
karate.set('testConfig', config);
"""
* match testConfig.baseUrl == 'https://staging-api.example.com'
* match testConfig.timeout == 10000
* assert testConfig.debug == true
Common Patterns
Environment-Specific Files
Load different files based on environment:
Feature: Environment-specific configuration
Scenario: Load config for current environment
* def env = karate.env || 'dev'
* def config = read('classpath:config/' + env + '.json')
* def testData = read('test-data-' + env + '.json')
Given url config.baseUrl
And path 'users'
When method get
Then status 200
Request and Response Files
Use files to organize requests, responses, and schemas:
@fileBasedTests
Feature: File-based testing
Background:
* def createRequest = read('classpath:requests/createUser.json')
* def expectedResponse = read('classpath:responses/createUser.json')
Scenario: Create user with request/response files
Given url baseUrl
And path 'users'
And request createRequest
When method post
Then status 201
And match response == expectedResponse
Next Steps
Continue mastering Karate features:
- Build data-driven tests: Data-Driven Tests
- Apply file reading to API testing: HTTP Requests
- Reuse features with file operations: Reusability