CORE SYNTAX
Configuration Files
Karate's configuration system provides powerful mechanisms for managing test settings, environment-specific values, and shared utilities across your test suite.
karate-config.js
The primary configuration file that executes before every scenario, establishing the test context and shared variables.
Basic Structure
function fn() {
var env = karate.env; // get system property 'karate.env'
karate.log('karate.env system property was:', env);
if (!env) {
env = 'dev'; // default environment
}
var config = {
env: env,
appId: 'my-app',
apiUrl: 'https://api.example.com',
dbUrl: 'jdbc:mysql://localhost:3306/testdb',
};
// Environment-specific settings
if (env == 'dev') {
config.apiUrl = 'http://localhost:8080';
config.dbUrl = 'jdbc:mysql://localhost:3306/devdb';
} else if (env == 'qa') {
config.apiUrl = 'https://qa-api.example.com';
config.dbUrl = 'jdbc:mysql://qa-db:3306/qadb';
} else if (env == 'prod') {
config.apiUrl = 'https://api.example.com';
config.dbUrl = 'jdbc:mysql://prod-db:3306/proddb';
}
return config;
}
Configuration Variables
Access configuration variables in your tests:
Feature: Use configuration
Background:
* url apiUrl # from karate-config.js
* def appId = appId # available globally
Scenario: API test
* path '/apps', appId
* method get
* status 200
Dynamic Configuration
Generate dynamic values during configuration:
function fn() {
var config = {
// Static values
baseUrl: 'https://api.example.com',
// Dynamic values
requestId: java.util.UUID.randomUUID() + '',
timestamp: new Date().getTime(),
// Functions
generateToken: function () {
return 'token-' + java.util.UUID.randomUUID();
},
// Complex objects
defaultHeaders: {
'Content-Type': 'application/json',
'X-Client-Id': 'karate-tests',
'X-Request-Time': new Date().toISOString(),
},
};
// Configure global settings
karate.configure('connectTimeout', 30000);
karate.configure('readTimeout', 60000);
karate.configure('retry', { count: 3, interval: 2000 });
return config;
}
Environment-Specific Config
Manage different configurations for various environments using separate files that override base settings.
File Loading Rules
Karate follows these rules for loading configuration:
- Check custom directory: If
karate.config.dir
system property is set, look forkarate-config.js
in that directory - Default location: Otherwise, load
classpath:karate-config.js
- Environment override: If
karate.env
is set:- With
karate.config.dir
: Loadfile:<karate.config.dir>/karate-config-<env>.js
- Without
karate.config.dir
: Loadclasspath:karate-config-<env>.js
- With
- Merge configurations: Environment-specific settings override base configuration
Environment File Example
karate-config-dev.js:
function fn() {
var config = {
apiUrl: 'http://localhost:8080',
mockMode: true,
debugLevel: 'DEBUG',
credentials: {
username: 'devuser',
password: 'devpass123',
},
};
// Dev-only configurations
karate.configure('report', false);
karate.configure('ssl', false);
return config;
}
karate-config-prod.js:
function fn() {
var config = {
apiUrl: 'https://api.production.com',
mockMode: false,
debugLevel: 'ERROR',
credentials: {
// Production credentials from environment variables
username: java.lang.System.getenv('PROD_USER'),
password: java.lang.System.getenv('PROD_PASS'),
},
};
// Production configurations
karate.configure('ssl', true);
karate.configure('proxy', 'http://corporate-proxy:8080');
return config;
}
Security Considerations
Protect sensitive information in configuration files:
function fn() {
var env = karate.env;
var config = {};
// Load secrets from environment variables
config.apiKey = java.lang.System.getenv('API_KEY');
config.dbPassword = java.lang.System.getenv('DB_PASSWORD');
// Load from secure properties file (not in version control)
if (env == 'local') {
var props = karate.read('classpath:local-secrets.properties');
config.apiKey = props['api.key'];
config.dbPassword = props['db.password'];
}
// Validate required configurations
if (!config.apiKey) {
throw 'API_KEY environment variable is required';
}
return config;
}
Add to .gitignore:
# Ignore local configuration files
karate-config-local.js
karate-config-*.js
local-secrets.properties
*.credentials
karate-base.js
Advanced configuration for framework builders, loaded before any other configuration files.
Framework Configuration
Create reusable framework configurations:
// classpath:karate-base.js
function fn() {
// Base framework configuration
var config = {
frameworkVersion: '1.0.0',
// Default timeouts
defaultTimeout: 30000,
// Common utilities
utils: {
generateId: function () {
return 'ID-' + java.util.UUID.randomUUID();
},
formatDate: function (date) {
var sdf = new java.text.SimpleDateFormat('yyyy-MM-dd');
return sdf.format(date);
},
parseJson: function (text) {
return JSON.parse(text);
},
},
// Authentication helpers
auth: {
basic: function (user, pass) {
var encoded = java.util.Base64.encoder.encodeToString((user + ':' + pass).bytes);
return 'Basic ' + encoded;
},
bearer: function (token) {
return 'Bearer ' + token;
},
},
};
// Set framework defaults
karate.configure('logPrettyRequest', true);
karate.configure('logPrettyResponse', true);
return config;
}
Loading Hierarchy
Configuration files load in this order:
classpath:karate-base.js
(if exists)karate-config.js
(required)karate-config-<env>.js
(if env is set)
Each layer can access and override previous configurations:
// karate-config.js can access karate-base.js variables
function fn() {
var config = karate.get('config') || {}; // from karate-base.js
// Extend base configuration
config.apiUrl = 'https://api.example.com';
config.timeout = config.defaultTimeout || 30000;
return config;
}
Configuration Best Practices
Modular Configuration
Organize complex configurations into modules:
function fn() {
// Load modular configurations
var dbConfig = karate.read('classpath:config/database.json');
var apiConfig = karate.read('classpath:config/api.json');
var authConfig = karate.read('classpath:config/auth.json');
var config = {
db: dbConfig[karate.env] || dbConfig.default,
api: apiConfig[karate.env] || apiConfig.default,
auth: authConfig[karate.env] || authConfig.default,
};
return config;
}
Validation and Defaults
Ensure robust configuration with validation:
function fn() {
var env = karate.env || 'dev';
// Define required properties
var required = ['apiUrl', 'apiKey', 'timeout'];
// Load configuration
var config = {
env: env,
apiUrl: getEnvVar('API_URL', 'http://localhost:8080'),
apiKey: getEnvVar('API_KEY', null),
timeout: parseInt(getEnvVar('TIMEOUT', '30000')),
};
// Validate required properties
required.forEach(function (prop) {
if (!config[prop]) {
throw 'Required configuration missing: ' + prop;
}
});
// Helper function
function getEnvVar(name, defaultValue) {
return java.lang.System.getenv(name) || karate.properties[name.toLowerCase()] || defaultValue;
}
return config;
}
Shared Utilities
Create reusable utilities in configuration:
function fn() {
var config = {
// Data generators
random: {
email: function () {
return 'user' + new Date().getTime() + '@example.com';
},
phone: function () {
return '+1' + Math.floor(Math.random() * 9000000000 + 1000000000);
},
uuid: function () {
return java.util.UUID.randomUUID() + '';
},
},
// Date utilities
dates: {
today: function () {
return new java.util.Date();
},
tomorrow: function () {
var cal = java.util.Calendar.getInstance();
cal.add(java.util.Calendar.DATE, 1);
return cal.getTime();
},
format: function (date, pattern) {
var sdf = new java.text.SimpleDateFormat(pattern);
return sdf.format(date);
},
},
// Validation helpers
validators: {
isEmail: function (email) {
return email.match(/^[\w\.-]+@[\w\.-]+\.\w+$/);
},
isUUID: function (uuid) {
return uuid.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
},
},
};
return config;
}
Troubleshooting
Configuration Not Loading
Debug configuration loading issues:
function fn() {
karate.log('=== Configuration Debug ===');
karate.log('karate.env:', karate.env);
karate.log('karate.config.dir:', karate.properties['karate.config.dir']);
karate.log('Working directory:', java.lang.System.getProperty('user.dir'));
karate.log('Classpath:', java.lang.System.getProperty('java.class.path'));
var config = {
debug: true,
};
return config;
}
Variable Access Issues
# Debug configuration variables
Scenario: Debug config
* print 'All config:', karate.get('config')
* print 'Specific var:', apiUrl
* def allVars = karate.info.scenarioVars
* print 'All scenario vars:', allVars
Next Steps
- Configure Environment Switching for different test environments
- Set up Tags for conditional configuration
- Learn about Hooks and Lifecycle for advanced configuration patterns