Q20 of 40 · Karate

How do you handle environment-specific configuration in Karate (karate-config.js)?

KarateMidkarateconfigurationkarate-configenvironmentsecrets-management

Short answer

Short answer: karate-config.js is evaluated before every feature. It reads karate.env (set with -Dkarate.env=staging) and returns a config object whose properties become scenario variables. Define environment-specific baseUrl, auth tokens, and timeouts. Never hard-code environment URLs in feature files — always reference config variables.

Detail

karate-config.js is the single entry point for environment configuration. Karate evaluates it as JavaScript before every feature run:

function fn() {
    var env = karate.env || 'dev';
    var config = { baseUrl: 'http://localhost:8080' };

    if (env === 'staging') {
        config.baseUrl = 'https://staging.api.example.com';
    }
    return config;
}

Activation — set karate.env via system property:

mvn test -Dkarate.env=staging

Or in CI as an environment variable that the JVM picks up.

Feature file usage:

Background:
  * url baseUrl          # uses the config variable
  * def token = adminToken

Secrets management: avoid hardcoding tokens in karate-config.js. Instead read from system properties or env vars:

config.apiToken = karate.properties['API_TOKEN'] || java.lang.System.getenv('API_TOKEN');

callonce in config: for expensive operations like fetching an OAuth token on startup, use karate.callSingle (runs once per JVM session, cached):

var authResult = karate.callSingle('classpath:helpers/get-token.feature', config);
config.authToken = authResult.accessToken;

// EXAMPLE

karate-config.js

function fn() {
  var env = karate.env || 'dev';

  // Base config (dev defaults)
  var config = {
    baseUrl:    'http://localhost:8080',
    adminUser:  'admin',
    adminPass:  'admin123'
  };

  if (env !== 'dev') {
    config.baseUrl   = java.lang.System.getenv('API_BASE_URL');
    config.adminUser = java.lang.System.getenv('ADMIN_USER');
    config.adminPass = java.lang.System.getenv('ADMIN_PASS');

    // Fetch token once for the whole suite — karate.callSingle caches across features
    var tokenResult = karate.callSingle('classpath:helpers/get-token.feature', config);
    config.bearerToken = tokenResult.accessToken;
  }

  karate.configure('connectTimeout', 10000);
  karate.configure('readTimeout',    20000);

  return config;
}

// WHAT INTERVIEWERS LOOK FOR

karate-config.js location and evaluation order, -Dkarate.env activation, reading secrets from env vars not hard-coding them, and karate.callSingle for expensive one-time setup. The distinction between call (per-feature) and callSingle (once per JVM) is a practical detail.

// COMMON PITFALL

Hard-coding staging and prod credentials in karate-config.js and committing them to version control. Always read secrets from environment variables or a secrets manager, never from the karate-config.js file itself.