REST Assured API Automation Interview Questions and Answers

REST Assured is a Java-based library that simplifies testing RESTful APIs by providing a domain-specific language (DSL) for writing readable and maintainable tests. It is widely used for automating API testing, allowing developers and testers to validate the correctness, performance, and behavior of APIs effortlessly.

Key Features of REST Assured :
  1. Supports RESTful API Testing:

    • Designed specifically for testing APIs that conform to REST principles.
  2. Simple and Readable Syntax:

    • Provides a DSL that makes test scripts concise and easy to understand, resembling natural language.
  3. Built-In HTTP Methods:

    • Offers direct support for common HTTP methods like GET, POST, PUT, DELETE, PATCH, etc.
  4. JSON and XML Support:

    • Natively supports validating and parsing JSON and XML responses.
  5. Built-In Assertions:

    • Allows verifying response status codes, headers, body, and other response attributes using a variety of assertion methods.
  6. Authentication Support:

    • Supports multiple authentication mechanisms such as Basic Auth, OAuth 1.0/2.0, Digest Auth, Preemptive Auth, and more.
  7. Integration with Testing Frameworks:

    • Easily integrates with popular testing frameworks like JUnit and TestNG.
  8. Support for Parameterization:

    • Enables testing APIs with query parameters, path parameters, form data, and request body payloads.
  9. Custom Filters:

    • Allows adding custom request/response filters for advanced use cases, like logging or manipulating requests/responses dynamically.
  1. Simplifies Testing:

    • Makes API testing easier compared to writing HTTP client code manually.
  2. Minimal Boilerplate Code:

    • Offers straightforward methods to send requests and validate responses, reducing test code verbosity.
  3. Comprehensive API Validation:

    • Allows validating multiple aspects of API responses such as status codes, headers, response time, and response bodies.
  4. Wide Format Compatibility:

    • Works seamlessly with JSONPath, XMLPath, and other libraries for response parsing.
  5. Flexibility:

    • Suitable for developers and QA engineers to perform both functional and integration testing.
    •  
Example Usage of REST Assured :

Here is a basic example of using REST Assured to test a RESTful API:

1. Import Required Dependencies

Add the REST Assured dependency to your Maven project:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.x.x</version> <!-- Use the latest version -->
    <scope>test</scope>
</dependency>
Advantages of REST Assured :
  1. Simple and Readable Syntax:

    • REST Assured provides a domain-specific language (DSL) that makes it easy to write and understand test cases, even for non-programmers.
    • Example: The given(), when(), and then() syntax improves code readability and organization.
  2. Comprehensive API Testing:

    • Supports all HTTP methods like GET, POST, PUT, DELETE, PATCH, etc., enabling end-to-end testing of RESTful APIs.
  3. Supports JSON and XML:

    • Built-in support for parsing and validating JSON and XML responses.
    • JSONPath and XMLPath integration make it easy to query specific parts of the response.
  4. Authentication Mechanisms:

    • Supports various authentication methods, including Basic Auth, Digest Auth, OAuth 1.0/2.0, Bearer Tokens, and Preemptive Auth.
  5. Seamless Integration:

    • Works well with popular Java testing frameworks like JUnit and TestNG for creating test suites and managing test cases.
  6. Efficient Assertions:

    • Provides built-in assertion methods for verifying response status codes, headers, body content, and response times.
    • Example: assertThat().statusCode(200).body("key", equalTo("value")).
  7. Custom Filters:

    • Allows adding custom filters for advanced use cases like logging requests and responses or dynamically modifying them during execution.
  8. Reusable Code:

    • Test scripts can be modularized and reused, saving time and effort when testing multiple APIs with similar structures.
  9. Free and Open-Source:

    • REST Assured is free to use, making it accessible to teams with limited budgets.
  10. Active Community Support:

  • A large, active community contributes to its development, ensuring regular updates and availability of resources like tutorials and forums.

Disadvantages of REST Assured :
  1. Java-Specific:

    • REST Assured is a Java-based library, limiting its use to Java projects or teams familiar with Java. It may not be suitable for teams using other languages like Python, Ruby, or JavaScript.
  2. Dependency Management:

    • Requires adding dependencies to the project (e.g., in Maven or Gradle), which can complicate setup if not managed properly.
  3. Limited to RESTful APIs:

    • Designed specifically for RESTful API testing. It cannot natively handle other API protocols like SOAP or GraphQL without additional libraries or workarounds.
  4. Steep Learning Curve for Non-Programmers:

    • While it simplifies API testing, REST Assured still requires basic knowledge of Java programming and testing frameworks, which can be a barrier for non-developers.
  5. No Built-In Reporting:

    • REST Assured does not provide built-in reporting capabilities. Test results must be integrated with external tools or frameworks (e.g., TestNG, JUnit, or custom reports).
  6. Performance Testing Limitations:

    • Not designed for large-scale performance or load testing. Tools like JMeter or Gatling are better suited for such use cases.
  7. Log Management:

    • While it allows request/response logging, the default log format may require customization to make logs more readable or useful for debugging.
  8. Thread Safety Concerns:

    • REST Assured is not inherently thread-safe. Running parallel tests requires additional measures, like ensuring no shared configurations are modified during test execution.
  9. Complex Setup for Advanced Use Cases:

    • Advanced features, such as dynamic request building or handling nested JSON, may require significant coding effort compared to simpler no-code or low-code tools.
  10. Limited Support for API Mocking:

  • REST Assured does not natively provide API mocking capabilities. External tools like WireMock are needed for simulating API responses during testing.
Validating the status code of a response is a fundamental step to ensure that the API behaves as expected. REST Assured provides a straightforward way to validate the status code using its built-in methods.

Example :
import io.restassured.RestAssured;
import io.restassured.response.Response;

public class StatusCodeValidation {
    public static void main(String[] args) {
        Response response = RestAssured.get("https://api.example.com/resource");
        int statusCode = response.getStatusCode();
        
        // Validate the status code
        if (statusCode == 200) {
            System.out.println("Status code is 200: OK");
        } else {
            System.out.println("Unexpected status code: " + statusCode);
        }
    }
}?
Given : Precondition setup (e.g., base URI, headers).

When : HTTP request (e.g., GET, POST).

Then : Response validation.

And : Additional validations or chaining.
Below is an example of how to use REST Assured to send a GET request and validate the response :
import io.restassured.RestAssured;
import io.restassured.response.Response;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class RestAssuredExample {

    public static void main(String[] args) {
        // Base URI
        RestAssured.baseURI = "https://jsonplaceholder.typicode.com";

        // Perform a GET request and validate the response
        given()
            .log().all() // Log request details
        .when()
            .get("/posts/1") // Send GET request to /posts/1
        .then()
            .log().all() // Log response details
            .assertThat()
            .statusCode(200) // Verify the status code is 200
            .body("id", equalTo(1)) // Verify the JSON field 'id' is 1
            .body("title", notNullValue()); // Verify the title is not null
    }
}?
To send a POST request with a JSON payload :
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class PostRequestExample {

    public static void main(String[] args) {
        given()
            .header("Content-Type", "application/json") // Set Content-Type
            .body("{ \"title\": \"foo\", \"body\": \"bar\", \"userId\": 1 }") // Set request body
        .when()
            .post("https://jsonplaceholder.typicode.com/posts") // Send POST request
        .then()
            .statusCode(201) // Verify the status code is 201 (Created)
            .body("id", notNullValue()); // Verify the response contains an 'id'
    }
}?
In REST Assured, query parameters can be added to a request using the queryParam method, which allows you to specify key-value pairs that will be appended to the URL.

Example :
import io.restassured.RestAssured;
import io.restassured.response.Response;

public class QueryParamExample {
    public static void main(String[] args) {
        Response response = RestAssured.given()
            .queryParam("param1", "value1")
            .queryParam("param2", "value2")
            .when()
            .get("https://api.example.com/resource");

        System.out.println(response.getBody().asString());
    }
}
?

In this example, the queryParam method is used to add two query parameters to the request.
To extract values from a JSON response, use the JsonPath class, which allows you to parse and query JSON data.

Example :
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.path.json.JsonPath;
public class ExtractValues {
    public static void main(String[] args) {
        Response response = RestAssured.get("https://api.example.com/data");
        JsonPath jsonPath = response.jsonPath();
        String value = jsonPath.getString("key");
        System.out.println("Extracted Value: " + value);
    }
}?

In this example, the jsonPath method is used to create a JsonPath object, which allows you to extract values using JSON path expressions.
Path parameters are used in RESTful APIs to identify specific resources. In REST Assured, you can handle path parameters using the pathParam method.

Example :
import io.restassured.RestAssured;
import io.restassured.response.Response;
public class PathParameterExample {
    public static void main(String[] args) {
        Response response = RestAssured.given()
            .pathParam("userId", 1)
            .when()
            .get("https://jsonplaceholder.typicode.com/users/{userId}");
        System.out.println(response.getBody().asString());
    }
}?

In this example, the pathParam method is used to set the userId path parameter.
Headers in REST Assured are used to pass additional information with an HTTP request or response. To set headers, use the header or headers methods.

Example :

import io.restassured.RestAssured;
import io.restassured.response.Response;
public class RestAssuredExample {
    public static void main(String[] args) {
        Response response = RestAssured.given()
            .header("Content-Type", "application/json")
            .header("Authorization", "Bearer your_token_here")
            .get("https://api.example.com/data");
        System.out.println(response.getStatusCode());
    }
}?

In this example, the header method is used to set the “Content-Type” and “Authorization” headers.
Logging request and response details is essential for debugging and ensuring that the API calls are functioning as expected. REST Assured provides built-in methods to log various parts of the request and response.

Example :

import io.restassured.RestAssured;
import io.restassured.response.Response;
public class APILoggingExample {
    public static void main(String[] args) {
        Response response = RestAssured.given()
            .log().all() // Log all request details
            .when()
            .get("https://jsonplaceholder.typicode.com/posts/1")
            .then()
            .log().all() // Log all response details
            .extract().response();
    }
}?

In this example, the log().all() method is used to log all details of the request and response.
Basic Authentication :
given()
    .auth().basic("username", "password")
.when()
    .get("/secure-endpoint");
?

Bearer Token :
given()
    .auth().oauth2("token")
.when()
    .get("/secure-endpoint");?
Use JSONPath for extracting values dynamically.
Response response = given().get("/endpoint");
String value = response.jsonPath().getString("field");?
15 .
What is the difference between response.body() and response.getBody().asString()?
* response.body() : Returns the response body object.

* response.getBody().asString() : Converts the response body to a string format.
Use tools like TestNG, JUnit, or external data sources (Excel, CSV).

Example with TestNG :

@Test(dataProvider = "data")
public void testApi(String param1, String param2) {
    given()
        .queryParam("key", param1)
    .when()
        .get("/endpoint")
    .then()
        .statusCode(200);
}
given()
    .config(RestAssured.config()
        .httpClient(HttpClientConfig.httpClientConfig()
            .setParam("http.connection.timeout", 5000)))
.when()
    .get("/endpoint");
18 .
What happens if the server returns a 4xx or 5xx error?
REST Assured will not throw an exception but return the response. You must explicitly validate the status code.

REST Assured can be seamlessly integrated into various CI/CD pipelines to automate API testing as part of your continuous integration and delivery processes. Here's a general approach and key considerations:

1. Choose a CI/CD Tool

  • Popular Options:
    • Jenkins
    • GitLab CI/CD
    • GitHub Actions
    • Azure DevOps
    • CircleCI

2. Project Setup

  • Build Tool: Use a build tool like Maven or Gradle to manage dependencies, build your project, and execute tests.
  • Test Framework: Integrate REST Assured into your testing framework (JUnit, TestNG).
  • Reporting: Generate test reports (e.g., using Allure, Extent Reports) for better analysis and visualization.

3. CI/CD Pipeline Configuration

  • Trigger: Define triggers for your pipeline (e.g., code commits, pull requests, scheduled runs).
  • Stages: Structure your pipeline into stages:
    • Build: Compile the code and package it.
    • Test: Execute the REST Assured tests.
    • Deploy: (Optional) Deploy the application to the target environment.
  • Jobs: Create jobs within each stage to execute specific tasks.
  • Artifacts: Publish test results and other relevant artifacts as part of the pipeline.

4. Example with Jenkins (using a Jenkinsfile)

Groovy :

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'mvn clean install'
            }
        }
        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
        stage('Report') {
            steps {
                // Publish test reports (e.g., using JUnit or Allure)
            }
        }
    }
}

5. Key Considerations

  • Environment Variables: Manage environment-specific configurations (e.g., API endpoints, credentials) using environment variables.
  • Test Data Management: Handle test data effectively (e.g., using data providers, external data sources).
  • Test Stability: Ensure your tests are stable and reliable to avoid false failures.
  • Reporting and Analysis: Leverage comprehensive reporting to track test results, identify trends, and improve test coverage.

Benefits of Integration

  • Early Bug Detection: Identify and fix issues early in the development lifecycle.
  • Improved Code Quality: Maintain high code quality through continuous testing.
  • Faster Time to Market: Accelerate the release process with automated testing.
  • Increased Confidence: Gain confidence in the stability and reliability of your APIs.
given()
    .relaxedHTTPSValidation()
.when()
    .get("/secure-endpoint");
Path parameters are part of the URL (e.g., /users/{id}).
given()
    .pathParam("id", 123)
.when()
    .get("/users/{id}");
?
22 .
What is the role of Filter in REST Assured?
Filters allow custom logic (e.g., logging, authentication) to be applied to every request or response.

RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
?
Filters in REST Assured allow you to apply common functionality to your requests and responses. They can be used for logging, adding headers, or modifying the request and response.

Example :
import io.restassured.filter.Filter;
import io.restassured.filter.FilterContext;
import io.restassured.response.Response;
import io.restassured.specification.FilterableRequestSpecification;
import io.restassured.specification.FilterableResponseSpecification;
public class CustomFilter implements Filter {
    @Override
    public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) {
        // Add a custom header
        requestSpec.header("Custom-Header", "value");
        
        // Log the request
        System.out.println("Request: " + requestSpec.getMethod() + " " + requestSpec.getURI());
        
        // Proceed with the request
        Response response = ctx.next(requestSpec, responseSpec);
        
        // Log the response
        System.out.println("Response: " + response.getStatusCode());
        
        return response;
    }
}?

To use the custom filter in your tests :
import static io.restassured.RestAssured.given;
public class APITest {
    public void testAPI() {
        given()
            .filter(new CustomFilter())
            .when()
            .get("https://api.example.com/data")
            .then()
            .statusCode(200);
    }
}?
REST Assured can be extended with custom matchers or assertions to tailor validation to specific requirements. Custom matchers can be created using the Hamcrest library, which REST Assured integrates with.

Example :
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class CustomMatchers {
    public static TypeSafeMatcher<String> containsSubstring(final String substring) {
        return new TypeSafeMatcher<String>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("a string containing ").appendValue(substring);
            }
            @Override
            protected boolean matchesSafely(String item) {
                return item.contains(substring);
            }
        };
    }
    public static void main(String[] args) {
        String response = "This is a sample response";
        assertThat(response, containsSubstring("sample"));
    }
}?

In this example, a custom matcher containsSubstring is created to check if a string contains a specific substring.
Error handling in REST Assured tests is important for ensuring that your API behaves as expected under various conditions. Here are some strategies to consider:

1. HTTP Status Code Validation: Always validate the HTTP status codes returned by the API.

2. Response Body Validation: Validate the response body to ensure that it contains the expected data.

3. Exception Handling: Use try-catch blocks to handle exceptions that may occur during the execution of the tests.

4. Logging: Implement logging to capture detailed information about the requests and responses.

Example :
import io.restassured.RestAssured;
import io.restassured.response.Response;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ApiTest {
    public static void main(String[] args) {
        try {
            Response response = given()
                .baseUri("https://api.example.com")
                .when()
                .get("/endpoint")
                .then()
                .statusCode(200)
                .body("key", equalTo("value"))
                .extract()
                .response();
            // Additional validation
            if (response.jsonPath().getString("anotherKey") == null) {
                throw new AssertionError("anotherKey is missing in the response");
            }
        } catch (Exception e) {
            System.err.println("Error occurred: " + e.getMessage());
        }
    }
}?
To integrate REST Assured with TestNG or JUnit, add the necessary dependencies to your project. If you are using Maven, add the following dependencies to your pom.xml file:

For TestNG :
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>4.3.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.3.0</version>
    <scope>test</scope>
</dependency>?


For JUnit :
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>4.3.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.1</version>
    <scope>test</scope>
</dependency>?
Next, write your test cases using REST Assured with TestNG or JUnit. Here is an example of a simple test case using TestNG :
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.testng.Assert;
import org.testng.annotations.Test;
public class ApiTest {
    @Test
    public void testGetRequest() {
        Response response = RestAssured.get("https://jsonplaceholder.typicode.com/posts/1");
        Assert.assertEquals(response.getStatusCode(), 200);
        Assert.assertEquals(response.jsonPath().getString("id"), "1");
    }
}?


And here is an example using JUnit :
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.Assert;
import org.junit.Test;
public class ApiTest {
    @Test
    public void testGetRequest() {
        Response response = RestAssured.get("https://jsonplaceholder.typicode.com/posts/1");
        Assert.assertEquals(200, response.getStatusCode());
        Assert.assertEquals("1", response.jsonPath().getString("id"));
    }
}?