Q20 of 40 · REST Assured

How would you parametrise the same REST Assured test across multiple datasets?

REST AssuredMidrest-assuredparameterized-testsjunit5testngdata-driven

Short answer

Short answer: With JUnit 5, use @ParameterizedTest with @MethodSource or @CsvSource — the test method receives dataset values and builds the REST Assured chain inside. With TestNG, use @DataProvider. REST Assured's stateless chain fits naturally into parameterised tests because there is no shared state to reset between runs.

Detail

JUnit 5 with @MethodSource — best for complex datasets:

static Stream<Arguments> invalidUsers() {
    return Stream.of(
        Arguments.of("",               "email must not be blank"),
        Arguments.of("not-an-email",   "email must be valid"),
        Arguments.of("a".repeat(256),  "email must not exceed 255 chars")
    );
}

@ParameterizedTest
@MethodSource("invalidUsers")
void createUser_withInvalidEmail_returns400(String email, String message) { ... }

JUnit 5 with @CsvSource — best for simple scalar pairs:

@ParameterizedTest
@CsvSource({ "GET,/users,200", "GET,/missing,404", "POST,/users,201" })
void endpoint_returnsExpectedStatus(String method, String path, int expected) { ... }

TestNG with @DataProvider:

@DataProvider
public Object[][] invalidEmails() {
    return new Object[][] { { "" }, { "no-at" }, { "@missing.local" } };
}

Each parameterised run is an independent test in reports — failures show the specific input that triggered them.

// EXAMPLE

static Stream<Arguments> invalidEmailCases() {
    return Stream.of(
        Arguments.of("",              "must not be blank"),
        Arguments.of("not-an-email",  "must be a well-formed email"),
        Arguments.of("a@",            "must be a well-formed email")
    );
}

@ParameterizedTest(name = "email={0} → {1}")
@MethodSource("invalidEmailCases")
void createUser_invalidEmail_returns400(String email, String expectedMsg) {
    given(reqSpec)
        .body(Map.of("name", "Alice", "email", email))
    .when()
        .post("/users")
    .then()
        .statusCode(400)
        .body("errors.email", hasItem(expectedMsg));
}

// WHAT INTERVIEWERS LOOK FOR

Correct JUnit 5 or TestNG parameterisation syntax, and understanding that each run produces an independent test report entry showing which input failed. Naming the @ParameterizedTest with name= is a quality signal.

// COMMON PITFALL

Looping over datasets inside a single @Test method — this reports one test (pass/fail) instead of N, making it impossible to see which dataset caused the failure without reading the stack trace.