Q28 of 40 · REST Assured
What's your approach to handling test data setup/teardown in REST Assured?
Short answer
Short answer: Use @BeforeEach to POST test resources via REST Assured, capture their IDs, and clean up in @AfterEach via DELETE. For expensive shared data, scope to @BeforeAll with test-specific filtering. Every test should set up exactly what it needs and clean up after itself — no implicit dependency on prior test execution order.
Detail
Per-test setup/teardown — the default:
private int userId;
@BeforeEach
void createUser() {
userId = given(reqSpec)
.body(Map.of("name", "Alice", "email", "alice-" + UUID.randomUUID() + "@test.com"))
.when().post("/users")
.then().statusCode(201)
.extract().path("id");
}
@AfterEach
void deleteUser() {
given(reqSpec).when().delete("/users/" + userId).then().statusCode(204);
}
UUID prefix for unique emails: prevents "already exists" conflicts in parallel execution.
Suite-level shared data (@BeforeAll): for costly data that many tests read but don't modify (a large catalogue, reference data). Tag it clearly as read-only; any test that modifies it must set up its own copy.
Idempotent teardown: always use anyOf(is(204), is(404)) in teardown assertions — if setup failed mid-way, the resource may not exist, and a strict 204 assertion in teardown obscures the real failure.
Anti-patterns:
- Tests that rely on data created by a previous test (order coupling)
- Hardcoded IDs (
userId = 1) that assume database state - No teardown — leaves dirty state that causes flakiness in the next run
// EXAMPLE
class OrderApiTest extends BaseApiTest {
private int userId;
private int orderId;
@BeforeEach
void setup() {
// Each test gets its own user + order — isolated by UUID email
userId = given(reqSpec)
.body(Map.of("name", "TestUser", "email", "u-" + UUID.randomUUID() + "@test.com"))
.when().post("/users")
.then().statusCode(201).extract().<Integer>path("id");
orderId = given(reqSpec)
.body(Map.of("userId", userId, "items", List.of(Map.of("sku", "A1", "qty", 2))))
.when().post("/orders")
.then().statusCode(201).extract().<Integer>path("id");
}
@AfterEach
void teardown() {
// Idempotent — 204 if deleted, 404 if setup failed before resource was created
given(reqSpec).when().delete("/orders/" + orderId)
.then().statusCode(anyOf(is(204), is(404)));
given(reqSpec).when().delete("/users/" + userId)
.then().statusCode(anyOf(is(204), is(404)));
}
@Test
void getOrder_returnsCorrectUserId() {
given(reqSpec).when().get("/orders/" + orderId)
.then().statusCode(200).body("userId", equalTo(userId));
}
}