Q7 of 17 · Framework design

How do you manage environment configuration (base URL, credentials, API keys) across environments in a test framework?

Framework designMidframework-designconfig-managementenvironmentsecuritydotenv

Short answer

Short answer: Store environment-specific values in .env files or a config.properties file (not in code), load them via environment variables at runtime, and select the active environment via a flag (ENV=staging npm test). Secrets never go in source control.

Detail

Pattern 1 — .env files per environment (Node.js):

# .env.local
BASE_URL=http://localhost:3000
API_KEY=local-dev-key

# .env.staging
BASE_URL=https://staging.example.com
API_KEY=staging-key-from-vault

# .env.production — NEVER commit this; load from CI secrets
// config/env.ts
import * as dotenv from 'dotenv';
dotenv.config({ path: `.env.${process.env.ENV ?? 'local'}` });

export const config = {
  baseUrl: process.env.BASE_URL ?? 'http://localhost:3000',
  apiKey:  process.env.API_KEY ?? '',
};

Run with: ENV=staging npx playwright test

Pattern 2 — config.properties (Java):

# src/test/resources/config/staging.properties
base.url=https://staging.example.com
browser=chrome
headless=true
String env = System.getProperty("env", "staging");
Properties config = new Properties();
config.load(getClass().getResourceAsStream("/config/" + env + ".properties"));
String baseUrl = config.getProperty("base.url");

Run with: mvn test -Denv=prod

Security rules:

  • .env.* files with real secrets are .gitignored — loaded from CI secrets manager (AWS Secrets Manager, GitHub Secrets, Vault)
  • Template .env.example committed with placeholder values
  • Never hardcode a real API key, password, or token anywhere in test code

Anti-patterns:

  • if (env == "prod") { baseUrl = "https://prod..." } inside test code — breaks separation of concerns
  • Committing .env with real credentials — a security incident waiting to happen

// WHAT INTERVIEWERS LOOK FOR

.env or properties file pattern. Runtime flag to select environment. Secrets in CI vault, not in code. Concrete example of how tests read config.

// COMMON PITFALL

Hardcoding base URLs or credentials inside the test or Page Object class. Any environment-specific value should come from config, not code.