Request & Response
HTTP methods, headers, validation, JsonPath
HTTP Methods
PUT - Full Update
PUT replaces the entire resource with the provided data:
@Test
public void updateUserWithPut() {
Map<String, String> updatedUser = new HashMap<>();
updatedUser.put("name", "Updated Name");
updatedUser.put("job", "Senior Engineer");
given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body(updatedUser)
.when()
.put("/api/users/2")
.then()
.statusCode(200)
.body("name", equalTo("Updated Name"))
.body("job", equalTo("Senior Engineer"))
.body("updatedAt", notNullValue());
}
PATCH - Partial Update
PATCH updates only the specified fields:
@Test
public void partialUpdateWithPatch() {
// Only updating the job field
String patchBody = """
{
"job": "Tech Lead"
}
""";
given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body(patchBody)
.when()
.patch("/api/users/2")
.then()
.statusCode(200)
.body("job", equalTo("Tech Lead"))
.body("updatedAt", notNullValue());
}
DELETE - Remove Resource
@Test
public void deleteUser() {
given()
.baseUri("https://reqres.in")
.when()
.delete("/api/users/2")
.then()
.statusCode(204); // No content on successful delete
}
@Test
public void verifyDeletedResourceNotFound() {
// Delete the resource
given().delete("https://reqres.in/api/users/999");
// Verify it's gone (depends on API implementation)
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/999")
.then()
.statusCode(404);
}
Working with Headers
Setting Request Headers
@Test
public void setRequestHeaders() {
given()
.baseUri("https://reqres.in")
// Single header
.header("Accept", "application/json")
.header("X-Custom-Header", "CustomValue")
// Content-Type shorthand
.contentType(ContentType.JSON)
.accept(ContentType.JSON)
.when()
.get("/api/users")
.then()
.statusCode(200);
}
Multiple Headers
@Test
public void setMultipleHeaders() {
// Using Headers object
Headers headers = new Headers(
new Header("Accept", "application/json"),
new Header("X-Request-ID", UUID.randomUUID().toString()),
new Header("X-Client-Version", "1.0.0")
);
given()
.baseUri("https://reqres.in")
.headers(headers)
.when()
.get("/api/users")
.then()
.statusCode(200);
}
@Test
public void headersFromMap() {
Map<String, String> headerMap = new HashMap<>();
headerMap.put("Accept", "application/json");
headerMap.put("X-Api-Version", "v2");
given()
.headers(headerMap)
.when()
.get("https://reqres.in/api/users")
.then()
.statusCode(200);
}
Validating Response Headers
@Test
public void validateResponseHeaders() {
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users")
.then()
.statusCode(200)
// Exact match
.header("Content-Type", "application/json; charset=utf-8")
// Partial match
.header("Content-Type", containsString("application/json"))
// Check header exists
.header("Date", notNullValue())
// Multiple header validations
.headers("Content-Type", containsString("json"),
"Transfer-Encoding", equalTo("chunked"));
}
@Test
public void extractHeaders() {
Response response = given()
.get("https://reqres.in/api/users")
.then()
.extract().response();
// Get single header
String contentType = response.getHeader("Content-Type");
// Get all headers
Headers allHeaders = response.getHeaders();
for (Header header : allHeaders) {
System.out.println(header.getName() + ": " + header.getValue());
}
}
Query & Path Parameters
Query Parameters
Query params appear after ? in URL: /users?page=1&per_page=5
@Test
public void queryParameters() {
given()
.baseUri("https://reqres.in")
// Individual params
.queryParam("page", 2)
.queryParam("per_page", 3)
.when()
.get("/api/users")
.then()
.statusCode(200)
.body("page", equalTo(2))
.body("per_page", equalTo(3));
}
@Test
public void multipleQueryParamsFromMap() {
Map<String, Object> params = new HashMap<>();
params.put("page", 1);
params.put("per_page", 10);
given()
.baseUri("https://reqres.in")
.queryParams(params)
.when()
.get("/api/users")
.then()
.statusCode(200);
}
@Test
public void multiValueQueryParam() {
// For APIs that accept: /search?tag=java&tag=selenium
given()
.baseUri("https://api.example.com")
.queryParam("tag", "java", "selenium", "testing")
.when()
.get("/search")
.then()
.statusCode(200);
}
Path Parameters
Path params are part of the URL path: /users/{id}
@Test
public void pathParameters() {
int userId = 5;
given()
.baseUri("https://reqres.in")
.pathParam("id", userId)
.when()
.get("/api/users/{id}")
.then()
.statusCode(200)
.body("data.id", equalTo(userId));
}
@Test
public void multiplePathParams() {
given()
.baseUri("https://api.example.com")
.pathParam("orgId", "acme-corp")
.pathParam("userId", 123)
.when()
.get("/organizations/{orgId}/users/{userId}")
.then()
.statusCode(200);
}
@Test
public void pathParamsFromMap() {
Map<String, Object> pathParams = new HashMap<>();
pathParams.put("version", "v2");
pathParams.put("resource", "users");
pathParams.put("id", 42);
given()
.pathParams(pathParams)
.when()
.get("https://api.example.com/{version}/{resource}/{id}")
.then()
.statusCode(200);
}
Request Body Types
JSON Body
@Test
public void jsonRequestBody() {
// Using JSON string (Java 15+ text blocks)
String jsonBody = """
{
"name": "Test User",
"email": "test@example.com",
"address": {
"street": "123 Main St",
"city": "Boston"
},
"tags": ["premium", "verified"]
}
""";
given()
.contentType(ContentType.JSON)
.body(jsonBody)
.when()
.post("https://api.example.com/users")
.then()
.statusCode(201);
}
Form Data
@Test
public void formDataRequest() {
given()
.contentType(ContentType.URLENC) // application/x-www-form-urlencoded
.formParam("username", "testuser")
.formParam("password", "secret123")
.when()
.post("https://api.example.com/login")
.then()
.statusCode(200);
}
@Test
public void multipartFormData() {
given()
.multiPart("file", new File("test-data/document.pdf"))
.multiPart("description", "Test document")
.multiPart("category", "reports")
.when()
.post("https://api.example.com/upload")
.then()
.statusCode(201);
}
Nested JSON with POJO
// Address.java
public class Address {
private String street;
private String city;
private String zipCode;
// Constructors, getters, setters
}
// UserRequest.java
public class UserRequest {
private String name;
private String email;
private Address address;
private List<String> roles;
// Constructors, getters, setters
}
@Test
public void nestedJsonWithPojo() {
Address address = new Address("456 Oak Ave", "Seattle", "98101");
UserRequest user = new UserRequest();
user.setName("Jane Doe");
user.setEmail("jane@example.com");
user.setAddress(address);
user.setRoles(Arrays.asList("admin", "user"));
given()
.contentType(ContentType.JSON)
.body(user) // Serialized to nested JSON
.when()
.post("https://api.example.com/users")
.then()
.statusCode(201);
}
JsonPath Expressions
JsonPath is a query language for JSON, similar to XPath for XML.
Sample Response
{
"page": 1,
"total": 12,
"data": [
{
"id": 1,
"email": "george@reqres.in",
"first_name": "George",
"last_name": "Bluth",
"avatar": "https://reqres.in/img/faces/1-image.jpg"
},
{
"id": 2,
"email": "janet@reqres.in",
"first_name": "Janet",
"last_name": "Weaver",
"avatar": "https://reqres.in/img/faces/2-image.jpg"
}
],
"support": {
"url": "https://reqres.in",
"text": "Support message"
}
}
JsonPath Syntax
| Expression | Description | Result |
|---|---|---|
page | Root level field | 1 |
data[0].email | First array element’s email | ”george@reqres.in” |
data[-1].id | Last array element’s id | 2 |
data.id | All ids from array | [1, 2] |
data.size() | Array size | 2 |
support.url | Nested object field | ”https://reqres.in” |
JsonPath in Validations
@Test
public void jsonPathValidations() {
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users?page=1")
.then()
.statusCode(200)
// Simple field
.body("page", equalTo(1))
// Array element by index
.body("data[0].id", equalTo(1))
.body("data[0].email", equalTo("george.bluth@reqres.in"))
// Array operations
.body("data.size()", equalTo(6))
.body("data.id", hasItems(1, 2, 3))
// Nested objects
.body("support.url", containsString("reqres"))
// Collection of values
.body("data.email", everyItem(containsString("@")));
}
Groovy GPath Expressions
Rest Assured uses Groovy’s GPath for advanced queries:
@Test
public void gPathExpressions() {
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users?page=1")
.then()
.statusCode(200)
// Find single item matching condition
.body("data.find { it.id == 1 }.email", equalTo("george.bluth@reqres.in"))
// Find all items matching condition
.body("data.findAll { it.id > 3 }.size()", greaterThan(0))
// Collect specific field from all items
.body("data.collect { it.first_name }", hasItem("George"))
// Sum, min, max
.body("data.id.sum()", greaterThan(0))
.body("data.id.min()", equalTo(1))
.body("data.id.max()", equalTo(6));
}
Extracting with JsonPath
@Test
public void extractWithJsonPath() {
Response response = given()
.baseUri("https://reqres.in")
.when()
.get("/api/users?page=1")
.then()
.extract().response();
// Using JsonPath object
JsonPath jsonPath = response.jsonPath();
// Extract single value
int page = jsonPath.getInt("page");
String firstEmail = jsonPath.getString("data[0].email");
// Extract list
List<String> emails = jsonPath.getList("data.email");
List<Integer> ids = jsonPath.getList("data.id", Integer.class);
// Extract as Map
Map<String, Object> firstUser = jsonPath.getMap("data[0]");
// Extract list of objects
List<Map<String, Object>> allUsers = jsonPath.getList("data");
System.out.println("Emails: " + emails);
System.out.println("First user: " + firstUser);
}
Response Extraction Patterns
Extract Full Response
@Test
public void extractFullResponse() {
Response response = given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.extract().response();
// Response metadata
int statusCode = response.getStatusCode();
String statusLine = response.getStatusLine();
long responseTime = response.getTime();
// Body as string
String body = response.getBody().asString();
// Pretty print
response.prettyPrint();
System.out.println("Status: " + statusCode);
System.out.println("Time: " + responseTime + "ms");
}
Extract Specific Fields
@Test
public void extractSpecificFields() {
// Extract single field directly
String email = given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.extract().path("data.email");
System.out.println("Email: " + email);
// Extract multiple values
Response response = given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/2")
.then()
.extract().response();
String firstName = response.path("data.first_name");
String lastName = response.path("data.last_name");
int id = response.path("data.id");
}
Deserialize to POJO
// UserResponse.java
public class UserResponse {
private UserData data;
private Support support;
// Nested classes
public static class UserData {
private int id;
private String email;
private String first_name;
private String last_name;
// getters, setters
}
public static class Support {
private String url;
private String text;
// getters, setters
}
// getters, setters
}
@Test
public void deserializeToPojo() {
UserResponse userResponse = given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.extract().as(UserResponse.class);
Assert.assertEquals(userResponse.getData().getId(), 2);
Assert.assertNotNull(userResponse.getData().getEmail());
}
Chaining Requests
@Test
public void chainedRequests() {
// Step 1: Create a user and get the ID
String userId = given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body(Map.of("name", "Test User", "job", "Tester"))
.when()
.post("/api/users")
.then()
.statusCode(201)
.extract().path("id");
// Step 2: Update the user using extracted ID
given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body(Map.of("name", "Updated User", "job", "Senior Tester"))
.when()
.put("/api/users/" + userId)
.then()
.statusCode(200)
.body("name", equalTo("Updated User"));
}
JSON Schema Validation
Validate that API responses conform to a defined schema structure.
Create JSON Schema
Save as src/test/resources/schemas/user-schema.json:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["data", "support"],
"properties": {
"data": {
"type": "object",
"required": ["id", "email", "first_name", "last_name"],
"properties": {
"id": { "type": "integer" },
"email": { "type": "string", "format": "email" },
"first_name": { "type": "string" },
"last_name": { "type": "string" },
"avatar": { "type": "string", "format": "uri" }
}
},
"support": {
"type": "object",
"properties": {
"url": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
Validate Against Schema
import static io.restassured.module.jsv.JsonSchemaValidator.*;
@Test
public void validateJsonSchema() {
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.body(matchesJsonSchemaInClasspath("schemas/user-schema.json"));
}
@Test
public void validateSchemaFromFile() {
File schemaFile = new File("src/test/resources/schemas/user-schema.json");
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.body(matchesJsonSchema(schemaFile));
}
Testing Error Scenarios
Testing 4xx Client Errors
@Test
public void testNotFound() {
given()
.baseUri("https://reqres.in")
.when()
.get("/api/users/999")
.then()
.statusCode(404)
.body(equalTo("{}")); // Empty response
}
@Test
public void testBadRequest() {
given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body("{invalid json}") // Malformed JSON
.when()
.post("/api/users")
.then()
.statusCode(400);
}
@Test
public void testUnauthorized() {
given()
.baseUri("https://api.example.com")
// No auth token provided
.when()
.get("/protected/resource")
.then()
.statusCode(401)
.body("error", equalTo("Unauthorized"));
}
Validating Error Response Structure
@Test
public void testLoginFailure() {
given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body(Map.of("email", "peter@klaven")) // Missing password
.when()
.post("/api/login")
.then()
.statusCode(400)
.body("error", equalTo("Missing password"));
}
@Test
public void testRegistrationValidation() {
given()
.baseUri("https://reqres.in")
.contentType(ContentType.JSON)
.body(Map.of("email", "invalid-email")) // Invalid email format
.when()
.post("/api/register")
.then()
.statusCode(400)
.body("error", notNullValue());
}