Skip to main content

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:

  1. Check custom directory: If karate.config.dir system property is set, look for karate-config.js in that directory
  2. Default location: Otherwise, load classpath:karate-config.js
  3. Environment override: If karate.env is set:
    • With karate.config.dir: Load file:<karate.config.dir>/karate-config-<env>.js
    • Without karate.config.dir: Load classpath:karate-config-<env>.js
  4. 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:

  1. classpath:karate-base.js (if exists)
  2. karate-config.js (required)
  3. 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