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

ExpressionDescriptionResult
pageRoot level field1
data[0].emailFirst array element’s email”george@reqres.in”
data[-1].idLast array element’s id2
data.idAll ids from array[1, 2]
data.size()Array size2
support.urlNested 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());
}