|

RestAssured + Cucumber BDD: Modern API Contract Testing for SDET Interviews

If you are still writing RestAssured tests as flat Java methods, you are missing the pattern that SDET interviewers actually care about in 2026: BDD-style contract testing with Cucumber integration.

Contents

Why BDD Matters for API Testing

Business stakeholders cannot read Java test methods. But they can read this:

Feature: User API Contract
  Scenario: Create a new user with valid data
    Given the API is available at "/api/users"
    When I send a POST request with valid user data
    Then the response status should be 201
    And the response should contain a "userId" field
    And the "email" field should match the request

Project Setup

<dependencies>
  <dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.4.0</version>
  </dependency>
  <dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>7.15.0</version>
  </dependency>
  <dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-testng</artifactId>
    <version>7.15.0</version>
  </dependency>
</dependencies>

Step Definitions with RestAssured

public class UserApiSteps {
    private RequestSpecification request;
    private Response response;

    @Given("the API is available at {string}")
    public void setupBaseUri(String endpoint) {
        request = RestAssured.given()
            .baseUri("https://api.example.com")
            .basePath(endpoint)
            .contentType(ContentType.JSON)
            .header("Authorization", "Bearer " + getToken());
    }

    @When("I send a POST request with valid user data")
    public void sendPostRequest() {
        String body = new JSONObject()
            .put("name", "Test User")
            .put("email", "test@example.com")
            .toString();
        response = request.body(body).post();
    }

    @Then("the response status should be {int}")
    public void verifyStatus(int expectedStatus) {
        response.then().statusCode(expectedStatus);
    }

    @And("the response should contain a {string} field")
    public void verifyFieldExists(String fieldName) {
        response.then().body(fieldName, notNullValue());
    }
}

Contract Validation Pattern

// Validate response matches JSON Schema
response.then()
    .assertThat()
    .body(matchesJsonSchemaInClasspath("schemas/user-response.json"));

Request Specification: Eliminate Duplication

RequestSpecification baseSpec = new RequestSpecBuilder()
    .setBaseUri("https://api.example.com")
    .addHeader("Content-Type", "application/json")
    .addHeader("Authorization", "Bearer " + token)
    .setRelaxedHTTPSValidation()
    .build();

// Reuse across all tests
given().spec(baseSpec).when().get("/users").then().statusCode(200);

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.