Q27 of 40 · REST Assured

How do you handle environment-specific configuration (dev/staging/prod) in REST Assured?

REST AssuredSeniorrest-assuredconfigurationenvironmentci-cdapi-testing

Short answer

Short answer: Load base URIs and credentials from environment variables resolved at suite startup in @BeforeAll, then inject into RequestSpecBuilder. Use a config library (Owner, Typesafe Config) for typed, validated properties. Never hard-code URLs — a CI pipeline should target any environment by setting one variable.

Detail

Pattern: resolve configuration at suite startup from the environment, not from hard-coded constants:

String baseUri  = requireNonNull(System.getenv("API_BASE_URL"),  "API_BASE_URL not set");
String apiToken = requireNonNull(System.getenv("API_TOKEN"),      "API_TOKEN not set");

Config library (Owner): typed, validated, and testable:

@Sources("classpath:api-${env}.properties")
interface ApiConfig extends Config {
    @Key("api.base.url") String baseUrl();
    @Key("api.token")    String token();
    @Key("api.timeout.ms") @DefaultValue("3000") int timeoutMs();
}

Files: api-dev.properties, api-staging.properties. Activated by -Denv=staging.

Multi-environment CI: the pipeline sets API_BASE_URL and API_TOKEN as secret variables. The same test binary runs against dev, staging, and prod without code changes.

Avoid: profile-switching frameworks that branch test logic per environment. If dev and staging need different assertion logic, the environments aren't comparable — fix the environment, not the test.

// EXAMPLE

ApiConfig.java

@Sources({
    "system:env",
    "system:properties",
    "classpath:api-${env}.properties",
    "classpath:api-default.properties"
})
public interface ApiConfig extends Config {
    @Key("API_BASE_URL")
    String baseUrl();

    @Key("API_TOKEN")
    String token();

    @Key("api.response.timeout.ms")
    @DefaultValue("3000")
    long responseTimeoutMs();
}

// In BaseApiTest
private static final ApiConfig config = ConfigFactory.create(ApiConfig.class);

@BeforeAll
static void buildSpecs() {
    reqSpec = new RequestSpecBuilder()
        .setBaseUri(config.baseUrl())
        .addHeader("Authorization", "Bearer " + config.token())
        .setContentType(ContentType.JSON)
        .build();

    resSpec = new ResponseSpecBuilder()
        .expectResponseTime(lessThan(config.responseTimeoutMs()), MILLISECONDS)
        .build();
}

// WHAT INTERVIEWERS LOOK FOR

Loading config from environment variables or a typed config library (not hard-coded), failing fast on missing required values (requireNonNull), and the principle that one test binary should run against any environment unchanged.

// COMMON PITFALL

Using if (env.equals("staging")) blocks in test code to vary assertions. This means dev and staging have different coverage — the tests aren't testing the same thing, so staging passing doesn't imply prod safety.