Handling Dynamic Tokens

Dynamic tokens are generated at runtime and should never be hardcoded in automation scripts.

Workflow

  1. Send a Login or Token Generation API request.
  2. Extract the token from the response.
  3. Store the token in a variable.
  4. Pass the token in the Authorization header of subsequent API requests.

REST Assured Example

Response response = given()
        .contentType(ContentType.JSON)
        .body(loginPayload)
.when()
        .post("/login");

String token = response.jsonPath().getString("token");

Use the extracted token in the next request:

given()
    .header("Authorization", "Bearer " + token)
.when()
    .get("/products");

Real-Time Example

In an e-commerce project, the Login API returned a JWT token. I called the Login API, extracted the token from the JSON response using jsonPath().getString("token"), and passed it in the Authorization header while calling the Product and Order APIs.

Why This Approach?

  • No hardcoded credentials
  • Works with dynamically generated tokens
  • Secure automation
  • Reusable across multiple test cases
  • Easy to maintain

Advertisement

Chaining Multiple APIs (End-to-End API Flow)

API chaining means using the response from one API as the input for another API.

This is essential because real-world applications contain multiple dependent APIs.

Workflow

Login API
      │
      ▼
Extract JWT Token
      │
      ▼
Create Product API
      │
      ▼
Extract Product ID
      │
      ▼
Place Order API
      │
      ▼
Extract Order ID
      │
      ▼
Get Order Details API
      │
      ▼
Validate Order

Steps

  1. Call the first API.
  2. Extract dynamic values like:
    • Token
    • User ID
    • Product ID
    • Order ID
    • Reference Number
  3. Pass these values to the next API.
  4. Continue until the complete workflow is automated.
  5. Validate every API response.

REST Assured Example

Step 1: Login

String token = loginResponse.jsonPath().getString("token");

Step 2: Create Product

String productId = productResponse.jsonPath().getString("productId");

Step 3: Place Order

String orderId = given()
        .header("Authorization", "Bearer " + token)
        .contentType(ContentType.JSON)
        .body(orderPayload(productId))
    .when()
        .post("/orders")
    .then()
        .statusCode(201)                            // validate before moving on
        .extract().path("orderId");

Step 4: Verify Order

given()
        .header("Authorization", "Bearer " + token)
        .pathParam("id", orderId)
    .when()
        .get("/orders/{id}")
    .then()
        .statusCode(200)
        .body("productId", equalTo(productId))
        .body("status", equalTo("PLACED"));

Each step asserts its status before extracting the next value — otherwise a failed step passes null along and the test fails later with a confusing error. Verifying the final state (the order really contains the product) is what makes the chain a test rather than a script.


Real-Time Example

In an e-commerce application, the Login API returned a JWT token. The Product API used the token and returned a Product ID. The Order API used both the Token and Product ID to place an order. Finally, the Order Details API verified the order using the Order ID.

This allowed automation of the complete purchase flow.


Another Common API Chain

Login
   │
   ▼
Get Token
   │
   ▼
Create User
   │
   ▼
Get User ID
   │
   ▼
Update User
   │
   ▼
Get User Details

Benefits

  • Simulates real user workflows
  • Eliminates hardcoded data
  • Improves end-to-end API validation
  • Supports complete business flow automation

Handling Flaky APIs

A flaky API is an API that fails intermittently due to temporary issues rather than actual defects.

Like a faulty bulb, it works sometimes and fails other times.

Common Reasons

  • Network latency
  • Server downtime
  • Timeout issues
  • High server load
  • Temporary infrastructure problems
  • Third-party service failures

How to Handle Flaky APIs

1. Implement Retry Mechanism

Retry failed requests a limited number of times.

Example:

  • Attempt 1
  • Attempt 2
  • Attempt 3

If still unsuccessful, mark the test as failed.


2. Increase Timeouts

Set explicit connection and read timeouts, so a hung call fails clearly instead of blocking the suite:

RestAssured.config = RestAssured.config().httpClient(
        HttpClientConfig.httpClientConfig()
                .setParam("http.connection.timeout", 5000)   // ms to establish the connection
                .setParam("http.socket.timeout", 15000));    // ms to wait for data

Timeouts should reflect agreed performance expectations — raising them until tests pass can hide real slowness.


3. Log Complete Request and Response

Capture:

  • Request URL
  • Headers
  • Request Body
  • Response Body
  • Status Code
  • Response Time

This simplifies root cause analysis.


4. Differentiate Temporary Failures from Real Defects

Retries should only recover transient issues.

Do not hide genuine application defects by retrying indefinitely.


Sample Retry Logic

static Response withRetry(Supplier<Response> call, int maxAttempts) throws InterruptedException {
    Response response = null;
    for (int attempt = 1; attempt <= maxAttempts; attempt++) {
        try {
            response = call.get();
            if (response.statusCode() < 500) return response;       // 2xx/4xx: return — a 4xx is a real result
        } catch (RuntimeException e) {                             // e.g. connection reset, timeout
            if (attempt == maxAttempts) throw e;
        }
        if (attempt < maxAttempts) Thread.sleep(1000L * attempt);  // back off: 1 s, 2 s, …
    }
    return response;
}

// Usage — the assertion still runs on the final response
Response res = withRetry(() -> given().spec(authSpec).get("/products"), 3);
res.then().statusCode(200);

The common snippet — loop until status 200, then break — has three problems: it retries every failure, including 4xx responses that signal a real defect; it retries immediately with no pause; and after the loop nothing fails the test if all attempts failed. This version retries only server errors and connection failures, backs off between attempts, and leaves the final assertion in the test. We checked the logic with simulated responses: 503 → 502 → 200 returned 200 on the third attempt, a 404 returned immediately, and three 500s returned the 500 so the assertion fails. Always log each retry so flaky endpoints are visible and get fixed. A closely related topic: Negative Testing & Error Handling in REST Assured.


Real-Time Example

I implemented a retry mechanism with three attempts. Temporary failures were recovered automatically, while actual defects still caused the test case to fail.


When Retry Logic is Useful


Advantages

  • Reduces false failures
  • Stable automation execution
  • Accurate defect reporting
  • Less manual rerun effort

Testing APIs Without Documentation

Sometimes API documentation is not available when testing begins.

Instead of waiting, testers explore the API to understand its behavior.

Think of it like learning a new board game by playing it.


Approach

Step 1

Identify available endpoints using:

  • Swagger UI
  • Postman Collection
  • Developer discussions
  • API Gateway

Step 2

Send sample requests.

Observe:

  • Status Codes
  • Response Body
  • Headers
  • Error Messages

Step 3

Understand

  • Request Parameters
  • Response Structure
  • Authentication
  • Required Headers

Step 4

Document everything discovered.

Include:

  • Endpoints
  • Request Format
  • Response Examples
  • Error Responses
  • Authentication Method

Step 5

Build automation scripts using the discovered behavior.

Later compare them with official documentation.


Real-Time Example

I used Postman to explore the APIs before documentation was available. After understanding the requests and responses, I created REST Assured automation scripts. When the official documentation became available, only minor updates were required.


Benefits

  • Testing starts immediately
  • No dependency on documentation
  • Faster project execution
  • Better understanding of APIs

Executing REST Assured Tests in Jenkins

Jenkins is a Continuous Integration (CI/CD) tool used to automatically execute REST Assured test suites.


Jenkins Workflow

Developer Pushes Code
          │
          ▼
      Git Repository
          │
          ▼
Jenkins Pulls Latest Code
          │
          ▼
 Maven Downloads Dependencies
          │
          ▼
 Execute REST Assured Tests
          │
          ▼
Generate TestNG / Allure Reports
          │
          ▼
Pass / Fail Build
          │
          ▼
Notify Team

Execution Steps

  1. Jenkins pulls the latest code from Git.
  2. Maven downloads dependencies.
  3. REST Assured test cases execute.
  4. Test reports are generated.
  5. Jenkins marks the build as:
    • Success
    • Failure
  6. Notifications are sent to the team.

Build Triggers

Jenkins jobs can run:

  • After every Git commit
  • Before deployment
  • Every night
  • On a scheduled basis

Why Jenkins?


Running REST Assured Tests Using Maven

Maven is the build automation and dependency management tool used for Java projects.

Dependencies are defined inside the pom.xml file.

Maven automatically:

  • Downloads dependencies
  • Compiles the project
  • Executes test cases

Common Maven Commands

Run Tests

mvn test

Clean and Execute Tests

mvn clean test

Install Project

mvn clean install

Execution Flow

pom.xml
     │
     ▼
Download Dependencies
     │
     ▼
Compile Source Code
     │
     ▼
Run TestNG Tests
     │
     ▼
Generate Reports

Real-Time Example

We execute REST Assured test suites using mvn clean test. Maven reads the pom.xml, downloads the required dependencies, compiles the project, and runs the TestNG test cases. The same command is used locally as well as in Jenkins CI pipelines.


Advantages

  • One command execution
  • Consistent builds
  • Automatic dependency management
  • Easy CI/CD integration

Automation Strategy: What Should Be Automated?

Not every API should be automated immediately.

Prioritize APIs that provide the highest business value and are executed frequently.


High Priority APIs

Automate APIs that are:

  • Business-critical
  • Stable
  • Frequently used
  • Executed during every regression cycle
  • Reusable across multiple test cases

Examples:

  • Login
  • Payment
  • Order
  • User Management
  • Product APIs

Lower Priority APIs

Avoid automating immediately if the APIs are:

  • Frequently changing
  • Under active development
  • Experimental
  • One-time use

Automate them after they become stable.


Effort Estimation Factors

Estimate automation effort based on:

  • Number of endpoints
  • Positive scenarios
  • Negative scenarios
  • Test data requirements
  • Framework reusability
  • Dependency between APIs

Code Review Checklist

Before merging automation code, verify:

  • No hardcoded values
  • Proper assertions
  • Reusable methods
  • Utility classes
  • Meaningful variable names
  • Framework standards followed
  • Clean code practices
  • Logging included
  • Exception handling implemented

Benefits

  • Faster regression testing
  • Reduced maintenance
  • Better code quality
  • Improved reusability
  • Stable automation framework

📚 Official documentation: REST Assured official site · MDN: HTTP

Frequently Asked Questions (FAQs)

1. How do you handle dynamic tokens?

Call the Login or Token Generation API, extract the token using:

jsonPath().getString("token");

Store it and pass it in the Authorization header for subsequent API requests.


2. How do you chain multiple APIs?

Extract dynamic values such as:

  • Token
  • User ID
  • Product ID
  • Order ID

Pass these values into subsequent requests as:

  • Headers
  • Path Parameters
  • Query Parameters
  • Request Body

Validate each API response before proceeding.


3. How do you handle flaky APIs?

  • Implement retry logic (typically 3 attempts)
  • Configure appropriate timeouts
  • Log requests and responses
  • Distinguish temporary failures from real defects
  • Avoid masking genuine application issues

4. How do you test APIs when documentation is unavailable?

  • Explore APIs using Swagger or Postman
  • Send sample requests
  • Analyze responses
  • Identify required parameters and headers
  • Document findings
  • Build automation scripts based on observed behavior

5. How are REST Assured tests executed in Jenkins?

Jenkins:

  1. Pulls the latest code from Git.
  2. Runs Maven commands (mvn test or mvn clean test).
  3. Executes REST Assured + TestNG test cases.
  4. Generates reports (TestNG / Allure).
  5. Marks the build as Passed or Failed.
  6. Notifies the team.

6. How do you execute REST Assured tests using Maven?

Use either of the following commands:

mvn test

or

mvn clean test

Maven reads the pom.xml, resolves dependencies, compiles the project, and executes the test suite locally or within CI/CD pipelines.


7. Which APIs should be automated first?

Prioritize APIs that are:

  • Business-critical
  • Stable
  • Frequently executed
  • Reusable
  • Included in every regression cycle

Examples include Login, Payment, Order, Product, and User Management APIs.


See how an extracted token or ID flows from one response into the next request in the REST Assured Visualizer.

From Real Projects

My API experience covers CRUD operations, HTTP methods, JSON path and validating JSON and XML responses, and my automation work was in Java with TestNG — the same building blocks these scenarios use. A CRUD flow is a chain in itself: the ID created by one request is what the read, update and delete requests depend on. Testsigma supports web, mobile and API test automation, so understanding APIs was part of understanding the product I was testing. Pass values between requests through variables and never hard-code IDs — it's what keeps a chained test reliable.