Handling multiple base URIs to achieve end-to-end API testing using REST Assured

Aarav gotra
Naukri Engineering
Published in
5 min readSep 7, 2020

I am the one who connects the two sides of a software

And

I respond back whenever someone HITS me

Yes, that’s right, I am an API endpoint!

These days APIs are everywhere — from ordering pizza online to paying bills, booking tickets, listening to music and what not. They have become a kind of industry standard for building applications. In short, they keep the world connected.

Now let’s focus on the title of this story. It contains a few keywords:

  • API Testing
  • REST Assured
  • Handling multiple base URIs

So what are they?

API Testing

Simplest API workflow diagram

API (Application Programming Interface) Testing is a testing type that checks the functionality, reliability, performance and security of APIs. In API Testing, instead of using a standard interface for input & output, a software is used to send requests to the API, receive output and validate the response. The look and feel of an application is not the focus here. It mainly concentrates on the business logic layer of the software architecture. API testing thus allows to find bugs early in the development process, even before the UI has been created.

While there is a single producer of an API, there can be a number of API consumers spread across a variety of platforms. A good quality API can greatly reduce the effort of integration for consumers and foster rapid development by preventing reiterations.

REST Assured

REST Assured is a Java library for validation of RESTful web services. Testing and validating REST services in Java is tougher than doing it with a dynamic language such as Ruby and Groovy. REST Assured has given the easiness of using these languages in Java domain. It provides the luxury of integrating tests with prevailing Java based testing frameworks such as Junit, TestNG and Selenium Webdriver.

API automation framework

Using REST Assured, we have developed an API automation framework, the components of which are explained briefly below:

Api Utils - This is the core engine of framework. It has functions to call the endpoint, set query params, set request body, validate response codes and response schema.

Response Schema - It contains the Json schema corresponding to each endpoint and is used for validating the response.

Api Services - It contains the positive and negative test scenarios for every endpoint.

Yaml Reader - It is a simple utility to parse the yaml file.

Test Data - Contains the test data against positive and negative scenarios for every endpoint.

Api Info - Contains details about request method, api path, response schema and success status code of every API endpoint in a yaml format. For example,

API Details
  • Method: Could be GET, PUT, POST, DELETE
  • Path: Path of API endpoint
  • successStatusCode: Expected status code of a successful response
  • responseSchema: Filename in which the response schema is present
  • API id: A unique identifier of an api. For example, in this case petstore and weather are the api ids.

The Yaml Reader reads all these details from the API Info yaml file and passes them to ApiUtils library where they get processed.

We just need to provide the information about API endpoints and it will automatically execute the endpoint by processing the given details.

Handling multiple base URIs in API automation

While we can easily create an automation framework using Rest Assured, handling of base URIs is not quite straightforward.

For example, the two curl requests below access resources over different base URIs,

  1. curl — location — request GET ‘http://restapi.demoqa.com/weather/Hyderabad'
  2. curl -X GET “https://petstore.swagger.io/v2/pet/123" -H “accept: application/json”

In many organizations, there are various applications which may have different base URIs. Not just that, a single application can also have different base URIs for different environments. In order to cover end-to-end scenarios, we need to handle them.

Let’s go step by step and see how we can solve this problem. Firstly, let’s talk about a few pieces of the API automation framework that we have used in this.

(i) Base URI Yaml - Along with the API information yaml described above, we also maintain a base URI information yaml that defines the base URI of different applications as per the environment. An application might have different base URIs on test, staging & production environments.

Base Uri Information

(ii) createSession() - This is the second component. It is actually a function that resides in the APIUTILS class mentioned above. createSession() helps in processing the api endpoint information. It takes two parameters as inputs,

  1. Api Id: The unique application identifier from ApiInfo file
  2. Application: Name of the application from BaseURI file
ApiUtils: CreateSession function

As shown in the picture, it reads the API method, path, request body and response schema according to the given Api Id and Application name. Then, it calls the getDefaultHttpRequestHeader function which is our third component.

(iii) getDefaultHttpRequestHeader() - This is where we handle the mutiple base URI at class level. It uses the setBaseURI function of RequestSpecBuilder class from io.restassured.builder.RequestSpecBuilder

getDefaultHttpRequestHeader() takes the application name as input, like, getDefaultHttpRequestHeader(“petstore”) and returns the request with base uri of petstore and also sets the default header in the same request for petstore application.

private  RequestSpecification getDefaultHttpRequestHeader(String application) {
if(application.equalsIgnoreCase("petstore")){
RequestSpecification spec = new RequestSpecBuilder().setBaseUri(applicationconfig.get("application.petstore."+env)).build();
return this.Request=RestAssured.given(spec).contentType("application/json\r\n").header("Accept", "application/json")
.header("User-Agent", "PostmanRuntime/7.20.1")
.header("Cache-Control", "no-cache")
.log().all();

// put default request header here for the petstore application
}
else if (application.equalsIgnoreCase("weather")){
RequestSpecification spec = new RequestSpecBuilder().setBaseUri(applicationconfig.get("application.weather."+env)).build();
return this.Request=RestAssured.given(spec).contentType("application/json\r\n")
.header("Accept", "application/json")
.log().all();
// put default request header here for the weather application

}
else{
// put deafult request header for the default application
return this.Request;
}

}

So, the automated testcase looks like this,

Automated Testcase

In this testcase, we are interacting with two applications at the same test case level by invoking the api endpoint with their application name using createSession() function.

This is how we can handle multiple base URIs during automation. For more details, you may refer to the sample code below,

https://github.com/naukri-engineering/api-automation-framework-sample

Hit the 👏 (claps) button to make it reachable to more audience.

--

--