Introduction

In our previous post, we explored Configuration (SSL, Proxy) for REST Assured, setting up secure and proxied connections. Now, we’ll dive into Basic Request Specification, a powerful feature in REST Assured that allows you to define reusable request configurations. This guide is tailored for beginners and experienced developers, offering clear explanations and practical examples to streamline your API testing.

Key Point: Request Specifications in REST Assured help you avoid repetitive code by defining common request settings, such as base URIs, headers, or parameters, making tests cleaner and more maintainable.

What is a Request Specification?

A Request Specification in REST Assured is a reusable template for configuring HTTP requests. Instead of repeating settings like the base URL, headers, or authentication details in every test, you can define them once and reuse them across multiple tests. This improves code readability, reduces duplication, and simplifies maintenance.

For example, if all your tests use the same API base URL or headers, a Request Specification lets you centralize these settings.

Creating a Basic Request Specification

REST Assured provides the RequestSpecification interface, which you can create using RestAssured.given() or the RequestSpecBuilder class. Let’s explore both approaches with examples.

Option 1: Using given()

The simplest way to create a Request Specification is by using given() to define settings and store them in a variable.


import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;

public class BasicRequestSpecTest {

    @Test
    public void testWithRequestSpec() {
        // Create a Request Specification
        RequestSpecification requestSpec = given()
            .baseUri("https://jsonplaceholder.typicode.com")
            .header("Content-Type", "application/json");

        // Use the specification in a test
        requestSpec
            .when()
                .get("/users/1")
            .then()
                .statusCode(200)
                .body("id", equalTo(1))
                .body("name", notNullValue());
    }
}

Explanation:

  • given(): Starts the Request Specification, allowing you to set properties like baseUri and header.
  • RequestSpecification requestSpec: Stores the configuration for reuse.
  • requestSpec.when(): Uses the specification to send a GET request.
  • The test validates the response status and body, reusing the predefined settings.
Important: Storing the specification in a variable allows you to reuse it across multiple tests, reducing code duplication.

Option 2: Using RequestSpecBuilder

For more complex configurations, use RequestSpecBuilder to build a Request Specification. This approach is more explicit and flexible.


import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;

public class RequestSpecBuilderTest {

    @Test
    public void testWithRequestSpecBuilder() {
        // Create a Request Specification using RequestSpecBuilder
        RequestSpecBuilder builder = new RequestSpecBuilder();
        builder.setBaseUri("https://jsonplaceholder.typicode.com");
        builder.addHeader("Content-Type", "application/json");
        RequestSpecification requestSpec = builder.build();

        // Use the specification in a test
        given()
            .spec(requestSpec)
            .when()
                .get("/users/1")
            .then()
                .statusCode(200)
                .body("id", equalTo(1))
                .body("email", containsString("@"));
    }
}

Explanation:

  • RequestSpecBuilder: Provides a builder pattern to configure the specification.
  • setBaseUri: Sets the base URL for all requests.
  • addHeader: Adds a common header (e.g., Content-Type).
  • build(): Creates the RequestSpecification object.
  • spec(requestSpec): Applies the specification to the test.

Step 1: Reusing a Request Specification Across Tests

To demonstrate reusability, let’s create a Request Specification and use it in multiple tests within the same class.


import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;

public class ReusableRequestSpecTest {

    private static RequestSpecification requestSpec;

    @BeforeAll
    public static void setup() {
        // Initialize Request Specification
        requestSpec = new RequestSpecBuilder()
            .setBaseUri("https://jsonplaceholder.typicode.com")
            .addHeader("Content-Type", "application/json")
            .build();
    }

    @Test
    public void testUserOne() {
        given()
            .spec(requestSpec)
            .when()
                .get("/users/1")
            .then()
                .statusCode(200)
                .body("id", equalTo(1));
    }

    @Test
    public void testUserTwo() {
        given()
            .spec(requestSpec)
            .when()
                .get("/users/2")
            .then()
                .statusCode(200)
                .body("id", equalTo(2));
    }
}

Explanation:

  • @BeforeAll: Initializes the RequestSpecification once before all tests (requires JUnit 5).
  • requestSpec: Reused across both tests, ensuring consistent settings.
  • Each test uses spec(requestSpec) to apply the configuration.
Pro Tip: Use @BeforeAll or @BeforeEach (JUnit) or @BeforeClass (TestNG) to set up Request Specifications for multiple tests, improving code organization.

Step 2: Adding More Configuration Options

Request Specifications can include additional settings, such as:

  • Query Parameters: Common parameters for all requests.
  • Authentication: Predefined credentials (covered in a later post).
  • Content Type: Default content type for requests.

Here’s an example with a query parameter:


import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;

public class RequestSpecWithParamsTest {

    @Test
    public void testWithQueryParam() {
        RequestSpecification requestSpec = new RequestSpecBuilder()
            .setBaseUri("https://jsonplaceholder.typicode.com")
            .addQueryParam("userId", 1)
            .addHeader("Content-Type", "application/json")
            .build();

        given()
            .spec(requestSpec)
            .when()
                .get("/posts")
            .then()
                .statusCode(200)
                .body("[0].userId", equalTo(1));
    }
}

Explanation:

  • addQueryParam: Adds a query parameter (userId=1) to all requests using this specification.
  • The test fetches posts for userId=1 and validates the response.

Step 3: Verify Setup with pom.xml

Ensure your pom.xml includes the necessary dependencies for REST Assured and JUnit:



    
        io.rest-assured
        rest-assured
        5.4.0
        test
    
    
        org.junit.jupiter
        junit-jupiter
        5.10.2
        test
    
    
        org.hamcrest
        hamcrest
        2.2
        test
    

Run the tests using mvn test or your IDE’s test runner to confirm the setup.

Tips for Beginners

  • Start Simple: Begin with basic settings like baseUri and header.
  • Reuse Specifications: Define specifications in a separate class or method for reuse across test suites.
  • Keep It Organized: Group related settings (e.g., headers, parameters) in a single specification.
  • Debug Issues: Enable logging (covered later) to troubleshoot request issues.
Troubleshooting Tip: If tests fail, verify the baseUri and ensure the API is accessible. Use RestAssured.enableLoggingOfRequestAndResponseIfValidationFails() to debug.

What’s Next?

In the next post, we’ll cover Query Parameters, exploring how to add and manage query parameters in REST Assured requests for more dynamic API testing. Stay tuned for more hands-on examples!