Advanced Chapter 16 · 10 min read

Environment & Configuration Management

Manage multiple environments (dev, staging, prod), handle secrets securely, use .env files, and switch configs at runtime.

Multi-Environment Configuration

Professional API tests run against multiple environments — development, staging, production. Each environment has different base URLs, credentials, and data. Your framework must switch between them seamlessly.

Configuration Strategies

  • Environment variables — Secure for CI/CD, no secrets in code
  • .env files — Local development convenience (never commit to git)
  • Config files — Structured settings per environment
  • CLI arguments — Override at runtime

Security Best Practices

Never hardcode tokens, passwords, or API keys. Use environment variables in CI/CD, .env files locally, and secret management tools (AWS Secrets Manager, HashiCorp Vault) in production.

config/env.config.js
// Environment-specific configuration
// npm install dotenv
import 'dotenv/config'; // loads .env file

const environments = {
  dev: {
    baseUrl: 'http://localhost:3000/api',
    timeout: 15000,
    logLevel: 'debug'
  },
  staging: {
    baseUrl: 'https://staging-api.example.com',
    timeout: 10000,
    logLevel: 'info'
  },
  prod: {
    baseUrl: 'https://api.example.com',
    timeout: 5000,
    logLevel: 'error'
  }
};

const env = process.env.TEST_ENV || 'dev';

export const config = {
  ...environments[env],
  apiToken: process.env.API_TOKEN || 'dev-token',
  apiKey: process.env.API_KEY || 'dev-key'
};

console.log(`Running against: ${env} (${config.baseUrl})`);
.env.example
# .env.example — copy to .env and fill in values
TEST_ENV=dev
API_TOKEN=your-token-here
API_KEY=your-api-key-here
DB_CONNECTION_STRING=mongodb://localhost:27017/test
ConfigManager.java
package com.apitesting.config;

import java.io.*;
import java.util.Properties;

public class ConfigManager {

    private static final Properties props = new Properties();
    private static String environment;

    static {
        environment = System.getProperty("env", "dev");
        loadConfig();
    }

    private static void loadConfig() {
        String configFile = "src/test/resources/config-" + environment + ".properties";
        try (FileInputStream fis = new FileInputStream(configFile)) {
            props.load(fis);
        } catch (IOException e) {
            throw new RuntimeException("Config not found: " + configFile);
        }
    }

    public static String getBaseUrl() {
        return props.getProperty("base.url");
    }

    public static String getApiToken() {
        // Environment variable takes priority (for CI/CD)
        String envToken = System.getenv("API_TOKEN");
        return envToken != null ? envToken : props.getProperty("api.token");
    }

    public static int getTimeout() {
        return Integer.parseInt(props.getProperty("timeout", "10000"));
    }

    public static String getEnvironment() {
        return environment;
    }
}

// Run with: mvn test -Denv=staging
// config-dev.properties:
//   base.url=http://localhost:3000/api
//   api.token=dev-token
//   timeout=15000

// config-staging.properties:
//   base.url=https://staging-api.example.com
//   api.token=staging-token
//   timeout=10000
config/env_config.py
"""Multi-environment configuration"""
import os
from dotenv import load_dotenv

load_dotenv()  # Load .env file

class BaseConfig:
    API_TOKEN = os.getenv('API_TOKEN', 'dev-token')
    API_KEY = os.getenv('API_KEY', 'dev-key')
    TIMEOUT = 10

class DevConfig(BaseConfig):
    BASE_URL = 'http://localhost:3000/api'
    TIMEOUT = 15
    LOG_LEVEL = 'DEBUG'

class StagingConfig(BaseConfig):
    BASE_URL = 'https://staging-api.example.com'
    TIMEOUT = 10
    LOG_LEVEL = 'INFO'

class ProdConfig(BaseConfig):
    BASE_URL = 'https://api.example.com'
    TIMEOUT = 5
    LOG_LEVEL = 'ERROR'

CONFIGS = {
    'dev': DevConfig,
    'staging': StagingConfig,
    'prod': ProdConfig
}

def get_config():
    env = os.getenv('TEST_ENV', 'dev')
    config = CONFIGS.get(env, DevConfig)
    print(f"Running against: {env} ({config.BASE_URL})")
    return config

# Usage in conftest.py:
# @pytest.fixture(scope='session')
# def config():
#     return get_config()
#
# @pytest.fixture(scope='session')
# def api(config):
#     return ApiClient(config.BASE_URL, timeout=config.TIMEOUT)

# Run with: TEST_ENV=staging pytest

API Testing Advanced Environment & Configuration Management

Written by PV

© 2026 All Rights Reserved