Automate Testing of Rest Services using Rest Assured


Rest Assured is a java library for testing of REST services. An official guide of Rest Assured can be found here: 
Rest Assured Official Guide

Introduction:

REST Services are used for communication between two platforms which may be are developed using different languages or technologies. The reason behind automation rest services is that it takes less time as well as it helps to find defects earlier as it can be tested before UI is developed.
What are Rest API's:
REST is the underlying architectural principle of the web. The amazing thing about the web is the fact that clients (browsers) and servers can interact in complex ways without the client knowing anything beforehand about the server and the resources it hosts. The key constraint is that the server and client must both agree on the media used, which in the case of the web is HTML.
Rest API's are stateless and cacheless. They don't store information. REST is implemented in XML as well as JSON. Conversion of JSON objects into Java objects is very easy. REST architecture follows the CRUD ( Create, Read, Update and Delete ) Style where Create means POST request, Read means GET request, Update means PUT request and Delete request.We can communicate with REST API with above four requests.
A Real Example of REST API can be found on below link:
Creating a Maven project in Eclipse for Rest Assured:
Step1 : Open Eclipse and Create a Maven Project. 
If you are not aware of Maven and how to create Maven project then you may follow the below article
How to Create Maven Project
Step 2: In pom.xml add the following dependencies

<dependencies>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.9.10</version>
     </dependency>

     <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>json-path</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>json-schema-validator</artifactId>
        <version>3.2.0</version>
    </dependency>
  </dependencies>



Step 3:  Add following build plugins in pom.xml

<build>
    <plugins>
    <!-- Following plugin executes the testng tests -->
       
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
            <!-- Suite testng xml file to consider for test execution -->
                <suiteXmlFiles>
                <suiteXmlFile>testng.xml</suiteXmlFile>
                </suiteXmlFiles>
            </configuration>
        </plugin>
        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
           </configuration>
        </plugin>

    </plugins>
</build>


Now let's write the first test to check the GET Request response:

Whenever we hit an API, HTTP status codes are returned that indicates whether the response was correct or wrong. Here we will see an example where we assert an HTTP status code. 200 code specifies that response was correct. 
Explanation of status codes is given at below link:

Way to work with GET Request:

We can view the JSON Response in UI form at the following site:
JSON Viewer . 
Copy and paste the response in text tab and view it  in Viewer tab.

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import static io.restassured.RestAssured.*;

public class GetStatusCodeTest {

 @BeforeClass
 public void setBaseUri() {
   RestAssured.baseURI = "https://maps.googleapis.com";
 }

 @Test
 public void testStatusCode() {
   Response res = given()
         .param("query", "restaurants in mumbai")
         .param("key", "Xyz")
         .get("/maps/api/place/textsearch/json");

   Assert.assertEquals(res.statusCode(), 200);
 }

 @Test
 public void testStatusCodeRestAssured() {

   given().param("query", "restaurants in mumbai")
          .param("key", "Xyz")
         .get("/maps/api/place/textsearch/json")
         .then()
         .assertThat().statusCode(200);

 }
}

Explanation of what JSON Path is and how we calculate it:

JSON Path is an XPath like query language for JSON that enables you to select nodes in a JSON document. The Retrieve Attributes with JSON Path filter enables you to retrieve specified message attributes from a JSON message using JSON Path expressions.

JSON Response Example:

{
   "results" : [
      {
         "formatted_address" : "First Floor, Raheja Tower,
         "geometry" : {
            "location" : {
               "lat" : 19.0609821,
               "lng" : 72.8626719
            }
         },
         "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
         "id" : "9ef6f9e6a4878ad752602bb619de4df229832904",
         "name" : "Yauatcha Mumbai",
         "opening_hours" : {
            "open_now" : true,
            "weekday_text" : []
         },
         "place_id" : "ChIJf3bw-efI5zsRtdR6zgH_FnQ",
         "rating" : 4.4,
         "types" : [ "restaurant", "food", "point_of_interest", "establishment" ]
      }
   ],
   "status" : "OK"

}


If we want to get formatted_address from above JSON Response then the JSON path will be $.results[0].formatted_address

To represent the head of JSON we use $ sign and “.” means next node and subsequent “.” may mean next node.


$.results[0].geometry.location.lat - Example of getting latitude
$.results[0].types[0] - Example to get the first type i.e. restaurant

JSON path can be tested at following site:


Explanation of how to get particular result from JSON Response:

testResult method details:
Here we extract the type of place using JSON path "results[0].types[0]" which we store in res variable and assert it using Test NG Assertion

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import static com.jayway.restassured.RestAssured.*;

import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;

public class GetRequestTest {

  @BeforeClass
  public void setBaseUri () {

    RestAssured.baseURI = "https://maps.googleapis.com";
  }

  @Test
  public void testResult ()  {
    String res  =given ().param ("query", "restaurants in mumbai")
    .param ("key", "AIzaSyBrhdZP1wWpMXVEvzpY4-3W-FKieCYhVXg")
    .get ("/maps/api/place/textsearch/json")
    .then ().contentType (ContentType.JSON)
    .extract ()
    .path ("results[0].types[0]");
    
    Assert.assertEquals (res, "restaurant");
    
  }
  
}


Install and Configure API Server:

JSON Server helps us to create a fake REST API. Following is the link:

Install JSON Server using the following command:







Create a db.json file as shown below and start JSON Server:
















Send Post Request as String body:


Explanation of postString method:
The data to add is send through the body in a string format.

Example Class:

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static com.jayway.restassured.RestAssured.*;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.response.Response;

public class PostRequestTest {

  @BeforeClass
  public void setBaseUri () {

    RestAssured.baseURI = "http://localhost:3000";
  }

@Test
  public void postString () {
    
    given().body ("{\"id\":\"2\","
    +"\"title\":\"Hello Mumbai\","
    +"\"author\":\"StaffWriter\"}")
    .when ()
    .contentType (ContentType.JSON)
    .post ("/posts");
      
  }

  }

Now if you view the db.json file, data related to id=2 will be present.

Send POST request as a POST object:

First, we will create class using which we can define values that need to be passed . In this class, we create getter and setter methods of data that needs to be passed as POST object
                                                                                                                                                                
public class Posts {

  public String id;
  public String title;
  public String author;

  public void setId (String id) {

    this.id = id;
  }

  public void setTitle (String title) {

    this.title = title;
  }

  public void setAuthor (String author) {

    this.author = author;

  }

  public String getId () {

    return id;

  }

  public String getTitle () {

    return title;
  }

  public String getAuthor () {

    return author;
  }

}



Now let's see the test which will remain same as above the only difference that will remain is we will pass the post object instead of the string.

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import static com.jayway.restassured.RestAssured.*;

import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;
import com.restapiclass.Posts;

public class PostRequestTest {

 
  @BeforeClass
  public void setBaseUri () {

    RestAssured.baseURI = "http://localhost:3000";
  }

 
  @Test
  public void sendPostObject () {
    
    Posts post = new Posts();
    post.setId ("4");
    post.setTitle ("Hello India");
    post.setAuthor ("StaffWriter");
    
    given().body (post)
    .when ()
    .contentType (ContentType.JSON)
    .post ("/posts");
    
  }
  

Now if you view the db.json file, data related to id=4 will be present.

Way to send the PUT Request:


PUT request is used to update the existing records. In the body, we can send the string as well as Java object. But we always send Java object in the body. You need to specify the id to be updated in Post Url for the below example.

Following example is used To the update the data related to specific id using PUT request.


Explanation of updateUsingPut method:


We update the title to "Hello Bhutan" from "Hello India" and in the put, we are passing the id to be updated in the URL.


import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static com.jayway.restassured.RestAssured.*;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;
import com.restapiclass.Posts;

public class PutRequestTest {

 
  @BeforeClass
  public void setBaseUri () {

    RestAssured.baseURI = "http://localhost:3000";
  }

 
  @Test
  public void updateUsingPut () {
    
    Posts post = new Posts();
    post.setId ("4");
    post.setTitle ("Hello Bhutan");
    post.setAuthor ("StaffWriter");
    
    given().body (post)
    .when ()
    .contentType (ContentType.JSON)
    .put ("/posts/4");
    
    
  }
}

In PUT request if we don't send some values then it will set it to null.

Way to send the PATCH Request:
Patch request is used when we want to update specific data related to that id.

Explanation of updateUsingPatch method:

Here we update the title to "Hello Maldives" from "Hello Bhutan without sending id and author as a part of POST Object.
package com.googlerestapi;

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import static com.jayway.restassured.RestAssured.*;

import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;
import com.restapiclass.Posts;

public class PatchRequestTest {

 
  @BeforeClass
  public void setBaseUri () {

    RestAssured.baseURI = "http://localhost:3000";
  }


  @Test
  public void updateUsingPatch ()  {
    
    Posts post = new Posts();
    post.setTitle("Hello Maldives");
    
    given().body (post)
    .when ()
    .contentType (ContentType.JSON)
    .patch ("/posts/4");
    
  }
}


Way to send the Delete Request:

The most simple one, where we just pass the id that needs to be deleted in URL . It will delete the data related to the specified id.


import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import static com.jayway.restassured.RestAssured.*;

import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;
import com.restapiclass.Posts;

public class DeleteRequestTest {

  @BeforeClass
  public void setBaseUri () {

    RestAssured.baseURI = "http://localhost:3000";
  }

    @Test
  public void delete ()  {
    
  
    given().
    when().contentType (ContentType.JSON).
    delete ("/posts/4");
    
  }
}


Now if you view db.json file then data related to id=4 will be deleted. 


Comments

Popular posts from this blog

Extracting an XML Response with Rest-Assured