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 likebaseUri
andheader
.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 theRequestSpecification
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 theRequestSpecification
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
andheader
. - 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 thebaseUri
and ensure the API is accessible. UseRestAssured.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!