API Automation using Rest Assured

REST API Test using Rest Assured

This test will hit a simple Restful web service. Details of the Restful Web service are mentioned in the below table:
 Endpoint http://restapi.demoqa.com/utilities/weather/city/<City>
HTTP method type: GET
 Comments:
 Here <City> means the city for which we are trying to retrieve the weather data. For e.g. if you want to know the weather conditions of Hyderabad, you would simple replace the <City> text with Hyderabad. The Restful resource URL for Hyderabad becomes: 
http://restapi.demoqa.com/utilities/weather/city/Hyderabad
 Response{
“City”: “Hyderabad”,
“Temperature”: “31.49 Degree celsius”,
“Humidity”: “62 Percent”,
“Weather Description”: “scattered clouds”,
“Wind Speed”: “3.6 Km per hour”,
“Wind Direction degree”: “270 Degree”
}

Why not just try to open http://restapi.demoqa.com/utilities/weather/city/Hyderabad in browser. Output will look like below:
REST API Test using Rest Assured

 In order to do the same thing using Rest-Assured, need to follow the steps below:
  1. Use the RestAssured class to generate a RequestSpecification for the URL: http://restapi.demoqa.com/utilities/weather/city/Hyderabad
  2. Specify the HTTP Method type
  3. Send the Request to the Server
  4. Get the Response back from the server
  5. Print the returned Response’s Body

How to Write REST API Test using Rest Assured?

Below is the code to hit the above end point. Let’s have a look at the code first and then at the explanation of the each line of code in the bottom.


import org.testng.annotations.Test;
import io.restassured.RestAssured;
import io.restassured.http.Method;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;

public class SimpleGetTest {

@Test
public void GetWeatherDetails()
{   
// Specify the base URL to the RESTful web service
RestAssured.baseURI = "http://restapi.demoqa.com/utilities/weather/city";

// Get the RequestSpecification of the request that you want to sent
// to the server. The server is specified by the BaseURI that we have
// specified in the above step.
RequestSpecification httpRequest = RestAssured.given();

// Make a request to the server by specifying the method Type and the method URL.
// This will return the Response from the server. Store the response in a variable.
Response response = httpRequest.request(Method.GET, "/Hyderabad");

// Now let us print the body of the message to see what response
// we have recieved from the server
String responseBody = response.getBody().asString();
System.out.println("Response Body is =>  " + responseBody);

}

}


The above code will produce the same response which was received when opened the same URL on a browser. Here is how the response will be printed in Eclipse console window.
WeatherResponsePrinted

Understanding the code

It is very important to understand individual lines of code. Let’s start with the first line of code in the test. 

Code line 1
This line uses a class called RestAssured to set up a request with the specified base URI. In our case the base URI is “http://restapi.demoqa.com/utilities/weather/city” . This is called the base URI because the is root address of the resource. Adding “/Hyderabad” at the end appends the exact resource name in the URI that we are trying to access.
Coming back to the class io.restassured.RestAssured , this class forms the basis of any kind of HTTP request that is required in the tests. Some key features of this class are
  • It creates HTTP Requests against a base URI
  • It supports creating Request of different HTTP method types (GET, POST, PUT, PATH, DELETE, UPDATE, HEAD and OPTIONS)
  • It makes HTTP communication with the server and passes on the Request that we created in our tests to the server.
  • Retrieves the Response from the server.
  • Helps validate the Response received from the server.
Internally this class uses HTTP builder library, Http builder is a Groovy language based HTTP client.

Code line 2
Once the request is set up, store the Request in a variable so that it can be modified. In this particular test, it is not required to modify the test. Still following the same approach to understand the basics.
Here RestAssured class is returning the Request against the base URI, as specified in line 1. Every Request in Rest-Assured library is represented by an interface called RequestSpecification. This interface allows to modify the request, like adding headers or adding authentication details. The word specification at the end is used to signify that how the request should look like, when sent to the server.

Code line 3
Now that RequestSpecification object is there, call the server to get the resource. This piece of code tells RequestSpecification to issue a request to the server.
Issuing request takes two arguments, first argument as HTTP Method Typeand second as String (“/Hyderabad”). This step actually sends the request to the remote server and gets a response back. This is why the return type of the request is specified as Response.
In Rest-Assured io.restassured.response.Response interface represents a Response returned from a server. This Response object will contain all the data sent by the server. Different method can be called on the Response object to get different parts of the Response. For e.g. call to get Headers, Status code and the body of the Response. In the next code line we will get the body of the Response.

Code line 4 and 5
This piece of code just tries to read the response and print the response.
Response interface has a method called getBody() , this method will return the body of the received response. Response Body is converted into a string value and printed on the console using the System.out.println statement.
Rest-Assured provides a lot of short hand methods which can help you write short code. The above test method can be written in a little different way, here is the code snippet. Please go through the code comments to understand the usage.


Validate Response Status using Rest Assured

This tutorial will cover the following verification :
  • Validating Response Status Code
  • Validating Error Status Code
  • Validating Response Status Line
In the next tutorial will cover the verification of Response Body Content.
From the previous First Rest-Assured Test example, a simple test which calls the Weather web service using a Get Method looks like this
Response object which represents the HTTP Response packet received from the Web service Server. HTTP Response contains Status, collection of Headers and a BodyHence, it becomes obvious that the Response object should provide mechanisms to read Status, Headers and Body.


How to Validate Response Status Code?

Response is an interface which lives in the package:io.restassured.responseThis interface has lots of method, mostly methods which can help to get parts of the received response. Take a look at some of the important methods. A simple Response followed by a dot (Response.) in eclipse would shown the available methods on the interface. As shown in the image below
Validate Response Status using Rest Assured
Noticed, getStatusCode() method can be used to get the status code of the Response. This method returns an integer and test will verify the value of this integer. TestNG Assert is used to verify the Status Code.

Below line of code extracts the status code from the message:
Once the status code is received, it is compared with the expected value of 200. 
Try running the test and notice that the test will pass. This is because the web service indeed returns a status code of 200. Try to print the value of statusCode.


How to validate an Error Status Code?

Status codes returned by the Server depends on whether the Request was successful or not. If the Request is successful, Status Code 200 is returned. status code. If the Request is not successful, Status Code other than 200 will be returned. Get a list of HTTP Status codes and there meanings on the W3 page
For ToolsQA Weather web service, let’s create another test which tests a negative scenario. The scenario is
  • Verify the Status Code returned by Weather web service on providing invalid City name.
City name that this test will use here is a long number, like 78789798798. Just copy the code from previous test and simple replace the city name with 78789798798. At this moment do not change the status code. The code looks like this

Now run your test class and check the result. Our negative test GetWeatherDetailsInvalidCity will fail. The reason is that the web service returns an error code of 400 when invalid city name is sent to it. However, the test is validating for expected value of 200. Look at the TesNG results, as shown in the image below.
StatusCodeTestFaliure

A quick change in the expected result in the code will make sure that this test passes. Update respective line as in the code below


How to Validate Response Status Line?

The first line returned in the Response from Server is called Status Line. Status line is composed of three sub strings
  • Http protocol version
  • Status Code
  • Status Code’s string value
During a success scenario a status line will look something like this “HTTP/1.1 200 OK”. First part is Http protocol (HTTP/1.1). Second is Status Code (200). Third is the Status message (OK).
Just as we go the Status Code in the line above, we can get the Status Line as well. To get the Status line we will simply call the Response.getStatusLine()method. Here is the code to do that.


Validate Response Header using Rest Assured

Every response that is received from a server contains zero or more headers. Headers are the part of Response that is sent by the server. Each header entry is basically a Key-Value pair. Headers are used to send across extra information by the server. This extra information is also referred to as Meta data of the Response.
Using the Headers a client can take intelligent decisions for e.g.
One of the Headers called Content-Type which tells how to interpret the data present in the Body of the Response. If the Body contains data in the form of JSON, then the value of Content-Type header will be application/json. Similarly if the data in the body is XML the Content-Typeheader will be application/xml.

How to read different Header Types from HTTP Response?

Let’s just see how to read a Header using Rest-Assured. To do that lets do a simple exercise in which the test would record the following Header Types from the Response:
  • Content-Type
  • Server
  • Content-Encoding
The Response interface provides direct methods to access individual header or all the Headers. Simply do a Response followed by a dot (Response.head), all the available methods to get headers will be displayed. Below image shows the available methods
Validate Response Header using Rest Assured

In the below code, .header(String arg0) method is used to get a particular header. In the argument of this method pass the exact header name.
In this code we are trying to get the Content-Type,  Server and Content-Encoding headers. The exact values will be printed out in the Console window using the System.out.println statement. The out of this test looks like this
ReadingIndividualHeaderNoteResponse.GetHeader(String headerName) method does exactly the same thing as the Response.Header(String headerName) method does. So the above can be written with replacing .Header with .GetHeader. Try it out yourself.

How to Print all the Headers from HTTP Response?

All the headers in a Response can also be printed by simply iterating over each Header. Response interface provides two methods
  • headers() : returns Headers
  • getHeaders() : returns Headers
This collection is represented by a class called io.restassured.http.Headers.Headers class implements the Iterable interface. Hencefor each (for( : )) loop can be used to read all the headers, as shown in the code below:

How to Validate Response Header using Rest Assured?

Now that we have have a mechanism to read a Header. Let’s write a test to validate the values of the header by putting an Assert. The code is simple and its mostly same as the above code. The only difference is that instead of having a print statement, TestNg Assert is used. Here is the code.


Read JSON Response Body using Rest Assured

Let us continue with the example of Weather web service that we used in the previous tutorials. When we request for the Weather details of a particular city, Server responds by sending the Weather details of the city as the Response Body. Response interface contains  two methods to get the Response Body
  • Response.body() : returns ResponseBody
  • Response.getBody() : returns ResponseBody

Read Json Response Body using Rest-Assured
Using these methods we can get an Object of type io.restassured.response.ResponseBody. This class represents the Body of a received Response. Using this class you can get and validate complete or parts of the Response Body. In the below code we will simply read the complete Response Body by using Response.getBody() and will print it out on the console window.

ResponseBody interface also has a method called .asString(), as used in the above code, which converts a ResponseBody into its String representation. If you run this test the output will look something like this:
Read Json Response Body using Rest AssuredNote: Response.body() method does exactly the same thing. So you can even use .body() method in the above code.

How to Validate Response Body contains some String?

ResponseBody can return the response body in a String format. We can use simple String methods to verify certain basic level of values in the Response. For e.g. we can use the String.contains() method to see if the Response contains a “Hyderabad” in it. The below code shows how to check for sub string presence.

Check String presence by ignoring alphabet casing
We can also ignore the casing using the String internal methods. To do this we will convert the Response in lower case and then compare it with our lower case string value. Below code demonstrates that.
The above two approaches suffer from a classical problem, what if the string “Hyderabad” is present in a wrong node or may be multiple instances of the same string are present. This is not a fool proof way of testing a particular node in the Response. There are better ways, Response interface gives you a mechanism to extract nodes based on a given JsonPath. There is a method called Response.JsonPath(), which returns a io.restassured.path.json.JsonPath Object. This object can be used to further query specific parts of the Response Json.
If you are not aware of JsonPath, please go through these tutorials

 

How to Extract a Node text from Response using JsonPath?

Let us continue with the above example and retrieve the City from the Response. To do so, we will simply get the JsonPath object from the Response interface and then query for the particular node. Just to be very clear, let us look at the Weather API response again.
In this response, if we want to go to the City node, all we have to do is have the following JsonPath: $.City. Try it out on the JsonPath Evaluator to verify the output.
Now let us look at the code, pay specific attention to the comments in the code.
Note: In Java JsonPath you do not need to have $ as the root node. You can completely skip that.
The output of the code passes the assertion and it also prints the City name retrieved from the Response. As shown in the image below

CityExtracted
On the similar lines you can extract any part of the Json response using the JsonPath implementation of Rest-Assured. This is very convenient, compact and easy way to write tests.

Sample Code to read all the nodes from Weather API Response

Now that we know how to read a node using JsonPath, here is a small piece of code that reads all the nodes and prints them to the Console.



POST Request using Rest Assured

Now let us make a POST request using Rest-Assured and before that, we need to understand the basics of POST Request.

 

What is POST verb of HTTP protocol?

HTTP POST Verb often called POST Method is used to send data to the Server. Common places where you can find a POST request is when you submit Form Data (HTML forms) on a web page. For e.g. submission of the registration form of Gmail. POST request usually result in changes on the Server like the addition of new data or maybe updated to existing data.
 
The data that is sent to the server in a POST request is sent in the body of the HTTP request. The type of body, XML, JSON or some other format is defined by the Content-Type header. If a POST request contains JSON data then the Content-Type header will have a value of application/jsonSimilarly, for a POST request containing XML the Content-Type header value will be application/xml.
 
Let us understand testing a POST web service using a live example. We will take a look at a registration web service. Web service details are
 
 Endpoint http://restapi.demoqa.com/customer/register
HTTP method type: POST
 Body: {
   “FirstName” : “value”
   “LastName” : “value”,
   “UserName” : “value”,
   “Password” : “value”,
   “Email”        : “Value”
 }
Success Response:{
“SuccessCode”: “OPERATION_SUCCESS”,
“Message”: “Operation completed successfully”
}
Failure Response:{
“FaultId”: “User already exists”,
“fault”: “FAULT_USER_ALREADY_EXISTS”
}

 

How to make a POST Request using Rest Assured?

In order to create JSON objects in the code, we will add a Simple JSONlibrary in the classpath. You can download Simple JSON from the maven using the following URL: https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simpleThen add the downloaded Jars to the classpath.

Let us begin step by step with the code
Step 1: Create a Request pointing to the Service Endpoint
This code is self explanatory. If you are not able to understand it you have missed the earlier tutorials in this series, please go through them first.

Step 2: Create a JSON request which contains all the fields
JSONObject is a class that is present in org.json.simple package. This class is a programmatic representation of a JSON string.  Take a look at the Request JSON above for our test web service, you will notice that there are multiple nodes in the JSON. Each node can be added using the JSONObject.put(String, String) method. Once you have added all the nodes you can get the String representation of JSONObject by callingJSONObject.toJSONString() method.

Step 3: Add JSON body in the request and send the Request
This web service accepts a JSON body. By this step, we have created our JSON body that needs to be sent. In this step, we will simply add the JSONString to the body of the HTTP Request and make sure that the Content-Typeheader field has a value of application/json.
You can put the JSON string in the body using the method called RequestSpecification.body(JsonString). This method lets you updated the content of HTTP Request Body. However, if you call this method multiple times the body will be updated to the latest JSON String.

Step 4: Validate the Response
Once we get the response back, all we have to do is validate parts of the response. Let us validate Success Code text in the Response, we will be using JsonPath. More on JsonPath can be found here.
Now that we have sent the Request and received a Response, let us validate Status Code and Response Body content. This is similar to the validation techniques that we discussed in previous tutorials. I would strongly suggest that you read those tutorials. The above code does the validation, it is self-explanatory.

Complete code
Here is the complete code for the above example


Changing the HTTP Verb on a POST Request

One of the key aspect of Web service testing is to verify negative scenarios on the Endpoint. There could be many negative scenarios, some of them are
  • Sending incomplete POST Data
  • Sending JSON data with incorrect syntax
  • Sending incorrect Verb in the Request.
Let us see what the impact will be if we send a GET request to an Endpoint that expects POST. Below code tries to do that, we will just print out the Response status code and the Response body to see if we get any error.
If you run this test following output is generated. In the output we can clearly see that the Response body tells us about the incorrect usage of HTTP Verb. The HTTP verb is also known as the Method types, given we actually make a remote method call and specify the type of the method call. 

Post request using Rest Assured

Comments

Post a Comment

Popular posts from this blog

Security Testing

Manage Jenkins