Q21 of 40 · REST Assured

How do you organise REST Assured tests in a Maven project for parallel execution?

REST AssuredMidrest-assuredparallel-executionmavensurefirethread-safety

Short answer

Short answer: Enable parallel execution via maven-surefire-plugin config (JUnit Platform provider for JUnit 5, or testng.xml for TestNG). Use local RequestSpecification instances per test class — never static RestAssured.* fields. Test isolation (independent data per test) is the prerequisite; parallelism is the config on top.

Detail

JUnit 5 — two-step: maven-surefire-plugin + junit-platform.properties:

<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.2.5</version>
    <configuration>
        <forkCount>1</forkCount>
    </configuration>
</plugin>
# junit-platform.properties
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.config.strategy=fixed
junit.jupiter.execution.parallel.config.fixed.parallelism=4

TestNG — configure in testng.xml:

<suite name="API Suite" parallel="classes" thread-count="4">
  <test name="Users">
    <classes><class name="com.example.UserApiTest"/></classes>
  </test>
</suite>

Thread safety checklist:

  • ✅ Use given(localSpec) not static RestAssured.baseURI
  • ✅ Independent test data per test (UUID-prefixed resources)
  • ✅ No shared mutable variables in test classes
  • ❌ Never set RestAssured.requestSpecification globally when running in parallel

// EXAMPLE

UserApiTest.java

// Thread-safe: each test method builds from a shared immutable spec
class UserApiTest extends BaseApiTest {

    @Test
    void createUser_isIdempotentWithSameIdempotencyKey() {
        // UUID prefix = unique across parallel threads
        String email = "alice-" + UUID.randomUUID() + "@example.com";
        Map<String, Object> body = Map.of("name", "Alice", "email", email);

        // First call
        int id1 = given(reqSpec).body(body)
            .when().post("/users")
            .then().statusCode(201)
            .extract().path("id");

        // Second call — same data, different user created (no idempotency key)
        int id2 = given(reqSpec).body(body)
            .when().post("/users")
            .then().statusCode(201)
            .extract().path("id");

        assertThat(id1).isNotEqualTo(id2); // each thread creates its own user
    }
}

// WHAT INTERVIEWERS LOOK FOR

Two-step parallel setup (maven-surefire config + junit-platform.properties), the thread safety of using local specs over static fields, and the prerequisite of test data isolation. The ordering — fix isolation first, then add parallelism — is a maturity signal.

// COMMON PITFALL

Enabling parallel execution without first isolating test data — two threads creating a user with the same email cause a 409 Conflict, which is a shared-state failure, not a test bug, and is hard to diagnose.