Introduction

In our REST Assured series, we’ve covered topics like Parallel Execution, API Chaining, and Asynchronous Requests, building a robust toolkit for API testing. Now, we’ll explore Session Management, a technique for handling authentication and stateful interactions in API tests, such as managing cookies, tokens, or session IDs. This guide demonstrates how to implement session management with REST Assured, with practical examples and best practices. It’s designed for beginners and experienced developers, ensuring your tests handle stateful APIs effectively.

Key Point: Session Management in REST Assured enables testing of APIs that require authentication or maintain state across requests, ensuring secure and reliable interactions.

What is Session Management?

Session Management involves maintaining state between API requests, typically for authentication or user-specific data. Common scenarios include:

  • Cookie-Based Sessions: Using cookies to track user sessions (e.g., session IDs).
  • Token-Based Authentication: Managing access tokens (e.g., JWT, OAuth) for authenticated requests.
  • Session Filters: Persisting headers or cookies across multiple requests.
  • Stateful Workflows: Testing APIs that require sequential, state-dependent calls.

REST Assured supports session management through:

  • Cookie Handling: Automatically or manually managing cookies.
  • Header Management: Storing and reusing tokens or headers.
  • Session Filters: Persisting session data across requests.
We’ll use https://httpbin.org to simulate authentication scenarios (e.g., cookies, tokens) and https://jsonplaceholder.typicode.com for stateless API testing where applicable.

Setting Up for Session Management

We’ll set up a Maven project with REST Assured, JUnit 5, and Allure for reporting, consistent with previous posts. No additional dependencies are needed for session management, as REST Assured’s built-in features handle cookies and headers.

Here’s the pom.xml, styled with your preferred Blogger format for XML syntax highlighting:



    4.0.0
    com.example
    rest-assured-session
    1.0-SNAPSHOT

    
        11
        2.27.0
        1.9.22
    

    
        
            io.rest-assured
            rest-assured
            5.4.0
            test
        
        
            org.junit.jupiter
            junit-jupiter
            5.10.2
            test
        
        
            org.hamcrest
            hamcrest
            2.2
            test
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.15.2
            test
        
        
            io.qameta.allure
            allure-junit5
            ${allure.version}
            test
        
    

    
        
            
                org.apache.maven.plugins
                maven-surefire-plugin
                3.2.5
                
                    
                        -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                    
                
                
                    
                        org.aspectj
                        aspectjweaver
                        ${aspectj.version}
                    
                
            
            
                io.qameta.allure
                allure-maven
                2.12.0
                
                    ${allure.version}
                
            
        
    

No additional setup is required for https://httpbin.org or https://jsonplaceholder.typicode.com. We’ll demonstrate session management with cookies, tokens, and session filters.

Implementing Session Management

Let’s explore how to implement session management with REST Assured, covering cookie-based sessions, token-based authentication, session filters, and Allure integration.

Example 1: Cookie-Based Session Management

Manage cookies to maintain a session across requests.


import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

@Feature("Session Management with REST Assured")
public class CookieSessionTest {

    @BeforeEach
    public void setup() {
        RestAssured.baseURI = "https://httpbin.org";
    }

    @Test
    @DisplayName("Test cookie-based session")
    @Description("Test maintaining a session using cookies")
    public void testCookieSession() {
        // Step 1: Set a cookie
        Response setCookieResponse = given()
            .cookie("session_id", "test_session_123")
            .log().all()
        .when()
            .get("/cookies")
        .then()
            .log().all()
            .statusCode(200)
            .body("cookies.session_id", equalTo("test_session_123"))
            .extract().response();

        // Step 2: Reuse the cookie in another request
        given()
            .cookie("session_id", "test_session_123")
            .log().all()
        .when()
            .get("/cookies")
        .then()
            .log().all()
            .statusCode(200)
            .body("cookies.session_id", equalTo("test_session_123"));
    }
}

Explanation:

  • Uses cookie() to set a session ID cookie for the request.
  • Verifies the cookie is sent and received using /cookies endpoint.
  • Reuses the same cookie in a subsequent request to simulate session persistence.
Important: Use cookies for stateful APIs that rely on session IDs stored in cookies.

Example 2: Token-Based Authentication

Manage a token obtained from a login API for authenticated requests.


import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

@Feature("Session Management with REST Assured")
public class TokenAuthTest {

    @BeforeEach
    public void setup() {
        RestAssured.baseURI = "https://httpbin.org";
    }

    @Test
    @DisplayName("Test token-based authentication")
    @Description("Test obtaining and using a token for authenticated requests")
    public void testTokenAuth() {
        // Step 1: Simulate obtaining a token
        String authBody = "{\"username\": \"test\", \"password\": \"pass\"}";
        Response authResponse = given()
            .header("Content-Type", "application/json")
            .body(authBody)
            .log().all()
        .when()
            .post("/post") // httpbin echoes the request body
        .then()
            .log().all()
            .statusCode(200)
            .extract().response();

        // Extract simulated token (using echoed username as placeholder)
        String token = authResponse.path("json.username"); // "test"

        // Step 2: Use token for authenticated request
        given()
            .header("Authorization", "Bearer " + token)
            .log().all()
        .when()
            .get("/bearer")
        .then()
            .log().all()
            .statusCode(200)
            .body("authenticated", equalTo(true));
    }
}

Explanation:

  • Simulates obtaining a token via a POST to /post (httpbin echoes the request).
  • Extracts a placeholder token (username “test”) from the response.
  • Uses the token in an Authorization header for a GET to /bearer.

Example 3: Using Session Filters

Use a session filter to persist cookies across requests.


import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import io.restassured.filter.session.SessionFilter;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

@Feature("Session Management with REST Assured")
public class SessionFilterTest {

    @BeforeEach
    public void setup() {
        RestAssured.baseURI = "https://httpbin.org";
    }

    @Test
    @DisplayName("Test session filter for cookies")
    @Description("Test persisting cookies using a session filter")
    public void testSessionFilter() {
        SessionFilter sessionFilter = new SessionFilter();

        // Step 1: Set a cookie with session filter
        given()
            .filter(sessionFilter)
            .cookie("session_id", "test_session_456")
            .log().all()
        .when()
            .get("/cookies")
        .then()
            .log().all()
            .statusCode(200)
            .body("cookies.session_id", equalTo("test_session_456"));

        // Step 2: Reuse session filter to maintain cookie
        given()
            .filter(sessionFilter)
            .log().all()
        .when()
            .get("/cookies")
        .then()
            .log().all()
            .statusCode(200)
            .body("cookies.session_id", equalTo("test_session_456"));
    }
}

Explanation:

  • SessionFilter: Persists cookies automatically across requests.
  • Applies the filter to both requests to maintain the session ID.
  • Simplifies cookie management for stateful APIs.
Pro Tip: Use SessionFilter for APIs that rely on server-side session management with cookies.

Example 4: Session Management with POJOs

Manage a session using a POJO for token storage.

Create a Token POJO:


public class Token {
    private String accessToken;

    public Token() {}

    public String getAccessToken() { return accessToken; }
    public void setAccessToken(String accessToken) { this.accessToken = accessToken; }
}

Test code:


import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

@Feature("Session Management with REST Assured")
public class POJOSessionTest {

    @BeforeEach
    public void setup() {
        RestAssured.baseURI = "https://httpbin.org";
    }

    @Test
    @DisplayName("Test session management with POJO")
    @Description("Test using a POJO to manage a token")
    public void testPOJOSession() {
        // Step 1: Simulate obtaining a token
        String authBody = "{\"access_token\": \"test_token_789\"}";
        Token token = given()
            .header("Content-Type", "application/json")
            .body(authBody)
            .log().all()
        .when()
            .post("/post")
        .then()
            .log().all()
            .statusCode(200)
            .extract().as(Token.class);

        // Step 2: Use token for authenticated request
        given()
            .header("Authorization", "Bearer " + token.getAccessToken())
            .log().all()
        .when()
            .get("/bearer")
        .then()
            .log().all()
            .statusCode(200)
            .body("authenticated", equalTo(true));
    }
}

Explanation:

  • Deserializes a simulated token response into a Token POJO.
  • Uses the POJO’s token for an authenticated request.
  • Provides structured token management for complex APIs.

Example 5: Session Management with Allure

Integrate session management with Allure reporting.


import io.qameta.allure.Allure;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import io.restassured.filter.session.SessionFilter;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

@Feature("Session Management with REST Assured")
public class AllureSessionTest {

    @BeforeEach
    public void setup() {
        RestAssured.baseURI = "https://httpbin.org";
    }

    @Test
    @DisplayName("Test session management with Allure")
    @Description("Test session management with Allure reporting")
    public void testSessionWithAllure() {
        SessionFilter sessionFilter = new SessionFilter();

        // Step 1: Set a cookie with session filter
        Response setCookieResponse = given()
            .filter(sessionFilter)
            .cookie("session_id", "test_session_999")
            .log().all()
        .when()
            .get("/cookies")
        .then()
            .log().all()
            .statusCode(200)
            .body("cookies.session_id", equalTo("test_session_999"))
            .extract().response();

        Allure.addAttachment("Set Cookie Response", "application/json", setCookieResponse.asString(), ".json");

        // Step 2: Reuse session filter
        Response reuseCookieResponse = given()
            .filter(sessionFilter)
            .log().all()
        .when()
            .get("/cookies")
        .then()
            .log().all()
            .statusCode(200)
            .body("cookies.session_id", equalTo("test_session_999"))
            .extract().response();

        Allure.addAttachment("Reuse Cookie Response", "application/json", reuseCookieResponse.asString(), ".json");
    }
}

Explanation:

  • Uses SessionFilter to persist cookies and attaches responses to Allure.
  • Logs session details for debugging in Allure reports.
  • Run mvn clean test and mvn allure:serve to view the report.

Integrating with CI/CD

Add session management tests to a GitHub Actions pipeline for automation.

Create or update .github/workflows/ci.yml:


name: REST Assured Session Management CI Pipeline

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK 11
        uses: actions/setup-java@v4
        with:
          java-version: '11'
          distribution: 'temurin'

      - name: Cache Maven dependencies
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: ${{ runner.os }}-maven-

      - name: Run tests
        run: mvn clean test

      - name: Generate Allure report
        run: mvn allure:report

      - name: Upload Allure results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: allure-results
          path: target/allure-results

      - name: Publish Allure report
        if: always()
        uses: simple-elf/allure-report-action@v1.7
        with:
          allure_results: target/allure-results
          gh_pages: gh-pages
          allure_report: allure-report

      - name: Deploy report to GitHub Pages
        if: always()
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: allure-report

Explanation:

  • Runs session management tests with mvn clean test.
  • Publishes Allure reports to GitHub Pages for visibility.

Tips for Beginners

  • Use Session Filters: Simplify cookie management with SessionFilter for stateful APIs.
  • Store Tokens Securely: Avoid hardcoding tokens; use environment variables or secure storage.
  • Validate Session Data: Always verify cookies or tokens in responses to ensure session integrity.
  • Enable Logging: Use log().all() to debug session-related issues.
Troubleshooting Tip: If a session fails, check logs for cookie or token details, verify API authentication requirements, and ensure headers are correctly set.

What’s Next?

This post enhances our REST Assured series by introducing Session Management, a critical technique for testing stateful APIs. To continue your learning, consider exploring:

  • GraphQL Testing: Testing GraphQL APIs with REST Assured.
  • Advanced Allure Reporting: Customizing reports with environments and categories.
  • End-to-End Testing: Combining REST Assured with Selenium for UI and API testing.
Stay tuned for more testing tutorials!