Users Online

· Guests Online: 95

· Members Online: 0

· Total Members: 188
· Newest Member: meenachowdary055

Forum Threads

Newest Threads
No Threads created
Hottest Threads
No Threads created

Latest Articles

Rest Assured Tutorial for REST API Automation Testing

 

In our previous chapter, we accomplished the sharing of test data in Cucumber Steps using Scenario Context. Subsequently, in this cImplement Configuration Readerhapter, we shall read the configuration values from a property file and use them in our code with the help of Configuration Reader.

If you may have noticed, so far, we are passing the user_Idand the base_Url values as hardcoded ones. However, the problem with hardcoded values is that they are non-maintainable. In other words, the changes in configuration value amount to making changes in several places in the code. Therefore, it is not a clean code practice.

As a solution to this, we will go for property file implementation in Java. If you wish to understand this on a conceptual level, you could refer to the Read Configurations from Property File. Let us learn how to implement the configurations from the property file.

Implement Configuration Reader to Read Project Configurations

We will follow the below steps and implement Read Configurations:

  1. How to Read Configurations from Property File
  2. Write Hard-Coded Values in the Property File
  3. Create a Configuration Reader File
  4. Use ConfigFileReader object in the TestContext file
  5. Run the Cucumber Test

How to Read Configurations from Property File

Firstly, right-click on the root Project and select New >> Folder.  Additionally, name it as configs. Moreover, we will keep config files with in the same folder.

Secondly, right-click the above-created folder and select New >> File. Additionally, name it as configuration.properties. Here, the .properties is the file extension.

Configuration Reader - Create Config Folder in Eclipse

Configuration Reader File Name

Step 2: Write Hard-Coded Values to Property File

If we look at our TestContext.java class,  we have been using two hardcoded values:

base_Url = http://bookstore.toolsqa.com
user_Id = 9b5f49ab-eea9-45f4-9d66-bcf56a531b85

In the configuration.properties file, we will move these values in key-pair format.

Configuration Reader - Create config file configuration.properties

Step 3: Create a Config File Reader

Firstly, right-click on the src/test/java and select New >> Package.  In addition to that, name it as dataProvider.  Moreover, all the data-readers files will be kept here in this package.

Secondly, right-click on the above created package and select New >> Class. After that, name it as ConfigFileReader.

ConfigReader.java

package configs;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class ConfigReader {
	private Properties properties;
	private static ConfigReader configReader;

    private ConfigReader() {
		BufferedReader reader;
	    	String propertyFilePath = "configs//Configuration.properties";
	        try {
	            reader = new BufferedReader(new FileReader(propertyFilePath));
	            properties = new Properties();
	            try {
	                properties.load(reader);
	                reader.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        } catch (FileNotFoundException e) {
	            e.printStackTrace();
	            throw new RuntimeException("Configuration.properties not found at " + propertyFilePath);
	        }		
	}

    public static ConfigReader getInstance( ) {
    	if(configReader == null) {
    		configReader = new ConfigReader();
    	}
        return configReader;
    }

    public String getBaseUrl() {
        String baseUrl = properties.getProperty("base_Url");
        if(baseUrl != null) return baseUrl;
        else throw new RuntimeException("base_Url not specified in the Configuration.properties file.");
    }

    public String getUserID() {
        String userId = properties.getProperty("user_Id");
        if(userId != null) return userId;
        else throw new RuntimeException("user_Id not specified in the Configuration.properties file.");
    }
}

Code Explanation:

How to Load Property File

BufferedReader reader = new BufferedReader(new FileReader(propertyFilePath));
Properties properties = new Properties();
properties.load(reader);
  • propertyFilePath: It would be a String variable containing the information of the config file path.
  • new FileReader(propertyFilePath): Creates a new FileReader containing file-name, to be read from.
  • new BufferedReader(new FileReader(propertyFilePath)): Reads the text from a character-input stream. Moreover, it ensures efficient reading of the characters, arrays, and lines by buffering the characters.
  • new Properties(): The Properties class represents a persistent set of properties. which can be saved to a stream or loaded from it. Additionally, the key and the corresponding value in the property list is a string.
  • properties.load(reader): It reads a property list of key and element pairs from the input character stream in a simple line-oriented format.

If you have noticed the class ConfigReader.java, we have implemented it as a singleton class. The Singleton class’s purpose is to control object creation, limiting the number of objects to only one. Additionally, there is only one Singleton instance. Therefore, any instance fields of a Singleton would occur only once per class, similar to static fields.

Why do we need Singleton class implementation?

Singleton pattern ensures the creation of only one instance of a class in the JVM. Moreover, it enables a global point of access to the object. In our case, we have ConfigReader.java, which should be accessed globally. So it is better to make the ConfigReader.java class as a singleton.

How to implement a Singleton Pattern?

The common concepts among several approaches to implement a Singleton pattern are:

  • Private constructor
  • Static field containing only it's an instance
  • A public static method returning an instance of the class
public class ConfigReader {
    // The Static member holds a single instance of the
    // ConfigReader class
    private static ConfigReader configReader;
    // ConfigReader prevents any other class from instantiating
    private ConfigReader() {
    }
    // Provides Global point of access
    public static ConfigReader getInstance() {
        if (configReader == null) {
            configReader = new ConfigReader();
        }
        return configReader;
    }
}

The ConfigReader.java class maintains a static reference to its instance. Additionally, it returns that reference from the static getInstance() method.

ConfigReader.java implements a private constructor so clients cannot instantiate ConfigReader instances.

ConfigFileReader Method

public String getBaseUrl() { 
      String baseUrl = properties.getProperty("base_Url"); 
      if(baseUrl != null) return baseUrl; 
      else throw new RuntimeException("base_Url not specified in the configuration.properties file."); 
}

properties.getBaseUrl(): Properties object gives us a .getProperty method. Additionally, the input is Key of the property sent as a parameter while the Value of the matched key is the output from the .properties file.

Moreover, if the properties file doesn't have the specified key, it returns the null. Hence, we have to put the null check and, in case of null, throw an exception to stop the test with stack trace information.

For more details, you can visit the article on Singleton Pattern in Java.

Step 4: Use ConfigFileReader object in the TestContext file

After making the necessary changes for the BASE_URL and USER_ID  inTextContext.java class:

private final String BASE_URL = "https://bookstore.toolsqa.com";
private EndPoints endPoints;

public TestContext() {
		endPoints = new EndPoints(BASE_URL);
		scenarioContext = new ScenarioContext();
		scenarioContext.setContext(Context.USER_ID, USER_ID);
	}

Consequently, the TextContext.java class transforms to:

package cucumber;

import apiEngine.EndPoints;
import configs.ConfigReader;
import enums.Context;

public class TestContext {

	private EndPoints endPoints = new EndPoints(ConfigReader.getInstance().getBaseUrl());
	private ScenarioContext scenarioContext;

	public TestContext() {
		scenarioContext = new ScenarioContext();
		scenarioContext.setContext(Context.USER_ID, ConfigReader.getInstance().getUserID());
	}

	public EndPoints getEndPoints() {
        return endPoints;
    }

	public ScenarioContext getScenarioContext() {
		return scenarioContext;
	}

}

Step 5: Run the Cucumber Test

Run the Tests as JUnit

We are all set now to run the updated Cucumber test. Firstly, Right -Click on ***TestRunner *class and Click Run As  >> JUnit Test. Cucumber runs the script in the same way as Selenium WebDriver.  Finally, the result will display in the JUnit tab of the console.

Image: Junit Results for Chapter Implementation of Configuration Reader class

Run the Tests from Cucumber Feature

To run the tests as a Cucumber Feature, right-click on the End2End_Test.feature file. Select the Run As>>Cucumber Feature.

Test Execution Result in Eclipse

Moreover, please try to implement the above changes in your framework, as explained above. Subsequently, our updated project folder structure of the framework will look likewise:

Project Explorer

The tests passed successfully with the changes we made to the Configuration Reader in our framework.

 

 

 

 

 

We have seen all the types of HTTP requests so far with respect to Rest Assured. Since these requests are distributed in various tutorials, a collective reference can serve as a bookmark for our readers as they get their hands dirty with rest assured. In this short post, we have combined rest assured examples with various HTTP requests with hands-on code for each of them. This is also reflected in the index as below:

  • Rest Assured examples with HTTP API Requests
    • HTTP GET Request Implementation
    • POST Request Implementation
    • HTTP PUT Request Implementation
    • HTTP DELETE Request Implementation

REST assured examples with HTTP API Requests

Rest Assured API supports functionality for various HTTP Requests like GET, POST, PUT, DELETE. Let us briefly discuss each of these methods and also walkthrough implementation of each method in Rest Assured.

HTTP GET Request Implementation

The HTTP GET request is used widely in the API world. We can use this request to fetch/get a resource from a server without sending any data with our requests. Since we are focusing on examples only in this post, you can refer to the GET request post here.

Let us now implement the GET request using Rest Assured. The code for the same is shown below.

import io.restassured.RestAssured;
import io.restassured.http.Method;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
 
public class RestAssuredAPITest {
@Test
public void GetBooksDetails() { 
	// Specify the base URL to the RESTful web service 
	RestAssured.baseURI = "https://demoqa.com/BookStore/v1/Books"; 
	// Get the RequestSpecification of the request to be sent to the server. 
	RequestSpecification httpRequest = RestAssured.given(); 
	// specify the method type (GET) and the parameters if any. 
	//In this case the request does not take any parameters 
	Response response = httpRequest.request(Method.GET, "");
	// Print the status and message body of the response received from the server 
	System.out.println("Status received => " + response.getStatusLine()); 
	System.out.println("Response=>" + response.prettyPrint());
   }
}

In the above code, we send a GET request to fetch the list of books and details of each book.

POST Request Implementation

Suppose we want to post/send some data on the server or create a resource on the server, then we go for an HTTP POST request. For more information on the same, you can refer to Understanding HTTP POST Request Method using Rest Assured for more details.

The following code implements the HTTP POST request using Rest Assured.

public void postRequestBooksAPI() 
{ 
   RestAssured.baseURI = "https://demoqa.com"; 
   RequestSpecification request = RestAssured.given();
   // JSONObject is a class that represents a Simple JSON. 
   // We can add Key - Value pairs using the put method 
   JSONObject requestParams = new JSONObject(); 
   requestParams.put("userId", "TQ123"); 
   requestParams.put("isbn", "9781449325862"); 
   // Add a header stating the Request body is a JSON 
   request.header("Content-Type", "application/json"); // Add the Json to the body of the request 
   request.body(requestParams.toJSONString()); // Post the request and check the response
   Response response = request.post("/BookStore/V1/Books"); 
   System.out.println("The status received: " + response.statusLine());
}

Here we post a request to BookStore and get the response from the API.

HTTP PUT Request Implementation - Rest Assured Examples

The HTTP PUT request either update a resource or substitutes the representation of the target resource with the full JSON request payload. For a detailed discussion on HTTP PUT requests, visit PUT Request using Rest Assured.

The code below makes a PUT request using Rest Assured.

import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.response.ResponseBody;
import io.restassured.specification.RequestSpecification;
public class UpdateBook {
     String userId= "toolsqa_test";
     String baseUrl="https://demoqa.com";
     String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTmFtZSI6InRlc3RpbmcxMjMiLCJwYXNzd29yZCI6IlBhc3N3b3JkQDEiLCJpYXQiOjE2Mjg1NjQyMjF9.lW8JJvJF7jKebbqPiHOBGtCAus8D9Nv1BK6IoIIMJQ4";
     String isbn ="9781449325865";
		 
     @Test
     public void updateBook() {
	  RestAssured.baseURI = baseUrl;
	  RequestSpecification httpRequest = RestAssured.given().header("Authorization", "Bearer " + token)
         .header("Content-Type", "application/json");
 
	  //Calling the Delete API with request body
	  Response res = httpRequest.body("{ \"isbn\": \"" + isbn + "\", \"userId\": \"" + userId + "\"}").put("/BookStore/v1/Book/9781449325862");
	 
	  //Fetching the response code from the request and validating the same
	  System.out.println("The response code - " +res.getStatusCode());
          Assert.assertEquals(res.getStatusCode(),200);
	     
	  }
}

Here, we update the book record with the given ISBN value by setting a new ISBN value and also setting the userId value.

HTTP DELETE Request Implementation

We can delete a resource from a server by making a DELETE request. We have a detailed description of the DELETE request in the article, DELETE Request using Rest Assured.

The following Rest assured example demonstrates the working of HTTP DELETE Request.

package bookstore;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.response.ResponseBody;
import io.restassured.specification.RequestSpecification;

public class DeleteBook {
	String userId= "de5d75d1-59b4-487e-b632-f18bc0665c0d";
	String baseUrl="https://demoqa.com";
	String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTmFtZSI6InRlc3RpbmcxMjMiLCJwYXNzd29yZCI6IlBhc3N3b3JkQDEiLCJpYXQiOjE2Mjg1NjQyMjF9.lW8JJvJF7jKebbqPiHOBGtCAus8D9Nv1BK6IoIIMJQ4";
	String isbn ="9781449337711";
		

	 
	  @Test
	  public void deleteBook() {
		  RestAssured.baseURI = baseUrl;
		  RequestSpecification httpRequest = RestAssured.given().header("Authorization", "Bearer " + token)
			         .header("Content-Type", "application/json");
		 
		  //Calling the Delete API with request body
		  Response res = httpRequest.body("{ \"isbn\": \"" + isbn + "\", \"userId\": \"" + userId + "\"}").delete("/BookStore/v1/Book");
	 
		  //Fetching the response code from the request and validating the same
		  System.out.println("The response code is - " +res.getStatusCode());
	      Assert.assertEquals(res.getStatusCode(),204);
     
	  }
}

The above code is for the HTTP DELETE request. Here we pass the ISBN and the userId for which the resource is to be deleted. The response obtained confirms the deletion (or if not).

Key TakeAways

In this article, we have presented programming examples of various HTTP requests using the REST Assured library. You can go through the details of each of the requests using the link provided in the description of each method above.

  • HTTP GET request is to fetch a particular resource from the server.
  • The HTTP POST request posts or sends information or create a new resource on the server.
  • HTTP PUT request updates a particular resource or substitutes the representation of the target resource.
  • An HTTP DELETE request deletes a particular resource from the server.

Each of the above methods can be programmatically simulated using Rest Assured.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Comments

No Comments have been Posted.

Post Comment

Please Login to Post a Comment.

Ratings

Rating is available to Members only.

Please login or register to vote.

No Ratings have been Posted.
Render time: 0.73 seconds
10,837,251 unique visits