Monday, October 24, 2016

Setup Rest Assured with Eclipse


Rest Assured is a java library for testing of REST services.Rest-Assured is an open-source Java Domain-Specific Language (DSL). It omits the requirement of using boiler-plate code to test complex API responses and supports both XML and JSON. 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 Click on File --> New --> Other 



Step 2: Select Maven project and Click on Next button










Step 3: Provide workspace location and click on Next button

















Step 4:
Select the highlighted archetype displayed in the below image and click on Next button.







Step 5: Specify Group Id, artifact id, package name and click on Finish button




Now a maven project will be available on your project list.

Step 6: In pom.xml file, present at bottom of your project add the following dependencies and save the file.

<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 7:  Add following build plugins in pom.xml

<build>
    <plugins>
       
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
                <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 right click on the project then click on Maven and the click on Update Project. 


All the required libraries will be downloaded and will be available for your project.

In next post, we will learn about how to work with GET Requests using Rest Assured.

Sunday, October 23, 2016

Testing GET Requests and their Responses using Rest Assured





 

What is a GET Request?

The GET method is used to retrieve information from the given server using a given URI. Requests using GET should only retrieve data and should have no other effect on the data.

Way to send GET Request using Rest Assured and Check Status Code:

For this exercise, we will use Google Places API ( Place Search ). You can view the API at below link :

We will learn about the Text Search GET request of Google Places API.

A Text Search request is an HTTP URL of the following form:
where output may be either of the following values:
  • json (recommended) indicates output in JavaScript Object Notation (JSON)
  • xml indicates output as XML
Certain parameters are required to initiate a search request. As is standard in URLs, all parameters are separated using the ampersand (&) character.

Testing HTTP Error Codes
We will verify that after calling the URL, the response code that we get is 200, which indicates, the response is correct. HTTP status codes indicate whether the response was correct or wrong.

Explanation of status codes is given at below link:
HTTP Status Codes Wiki

Let's look at an example now:
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")
     .when()
     .get ("/maps/api/place/textsearch/json");

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

 @Test
 public void testStatusCodeRestAssured () {

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

 }
}


Explanation of setBaseUri Method:
The entire URL that we will hit is as follows:
So the BaseUri is https://maps.googleapis.com
Explanation of testStatusCode Method:

Rest Assured follows the BDD ( Behaviour Driven Development ) approach for writing tests i.e Given- When - Then structure. In Given, we will mention the parameters while making the API call. When, is used for making the API call.
Then, is where we perform the assertion or check if the response is as expected.

The query parameters can be passed via param and key to access an API should be also passed via param, wherein param we will pass query and key.
Following document explains How to get an API Key:
The path can be passed through GET, where path is 
"/maps/api/place/textsearch/json"
Under the When, we perform a GET request to the specified URL.


The Response will be saved in Response variable and calling status code method will return the code which we will assert using Test NG'S assertEquals method.

Explanation of testStatusCodeRestAssured Method:
The response can also be checked using Rest Assured rather than using Test Ng Assertions. Under THEN, using assertThat method we check if the response is equal to 200.

In next post, we will learn about how to send the GET Request and print the Response.

Saturday, October 22, 2016

Extracting a JSON Response with Rest-Assured


In the earlier post, we studied about Testing GET Requests and their Responses using Rest Assured, before following this tutorial, I would recommend reading the previous one. In this post, we will learn about extracting JSON Response using Rest Assured. Once the response is extracted we will store it into Response class and later various tests can be performed to check whether extracted response is correct.
I would assume that everyone following this tutorial has knowledge of Java and TestNG. If you need help then please follow tutorials on Java and TestNG.

Now let's look at an example where we will search for a particular Railway Station in Mumbai City and print the response.
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import static io.restassured.RestAssured.*;

public class GetJsonResponseTest {

   @BeforeClass
   public void setBaseUri () {

     RestAssured.baseURI = "https://maps.googleapis.com";
   }
   
   @Test
   public void test01()  {
     Response res  = given ().param ("query", "Churchgate Station")
     .param ("key", "Xyz")
     .when()
     .get ("/maps/api/place/textsearch/json")
     .then()
     .contentType(ContentType.JSON)
     .extract().response();


     System.out.println (res.asString ());

   }

}
In setBaseUri method, We are simply setting the default URI  to use in all of our tests. Now when we write out a test that calls an API (as we will do in the next step), we don’t have to type in the full address of the API.

In test01 method, we are using the  given - when - then format. 
We start with given method and specify query and key parameter using the param method then we use the ‘when‘ method and use the ‘get’ method to call ‘Text Search API‘. 

Remember that we set the defaults for the base URI , so the full address of the API that is actually being called here ‘https://maps.googleapis.com/maps/api/place/textsearch/json?query=Churchgate%20Station&key=AIzaSyBrhdZP1wWpMXVEvzpY4-3W-FKieCYhVXg‘.

Now we use ‘then‘ part to check the response. We simply add a check ‘contentType(ContentType.JSON)‘ to make sure that the response we get is in JSON format.
Then we extract the response into the Response variable (res) by calling the‘extract().response()‘ methods. Later we convert the response into the string and print it on the console.

Following JSON Response will be printed on console:
{
   "html_attributions" : [],
   "results" : [
      {
         "formatted_address" : "Maharshi Karve Rd, Churchgate, Mumbai, Maharashtra 400020, India",
         "geometry" : {
            "location" : {
               "lat" : 18.9352871,
               "lng" : 72.82723969999999
            },
            "viewport" : {
               "northeast" : {
                  "lat" : 18.93530255,
                  "lng" : 72.82751705
               },
               "southwest" : {
                  "lat" : 18.93528195,
                  "lng" : 72.82714724999998
               }
            }
         },
         "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/train-71.png",
         "id" : "bd620744adf1ac386bca29ae21789e7a3497dd4a",
         "name" : "Churchgate",
         "photos" : [
            {
               "height" : 1750,
               "html_attributions" : [
                  "\u003ca href=\"https://maps.google.com/maps/contrib/100436573426357925098/photos\"\u003eSonu Kushwaha\u003c/a\u003e"
               ],
               "photo_reference" : "CoQBdwAAAMungiqPLNJiKTcsmr3NIsAjt12pD7xQf9WPviqcOGOWH7m_ajPHen0P1ASWBIwDGVNx2ZM4A80YaAoxHaMxH9w468ncaj91x-Xyn7HpVGWpbXoeomp0kkJK45hpgqOv6qiP0JVfeYLnmb3JDDTz95EfLH-CAm9CygwSlzxotCYXEhDQk_Y0EFeLkQKmUbYwnxVPGhRqb8GvTHiQX_rVseJdSuBhLofljA",
               "width" : 2498
            }
         ],
         "place_id" : "ChIJ9RNjZufR5zsRd6X3LdEWiZ0",
         "rating" : 4.4,
         "reference" : "CmRSAAAAkHys22E9AK8z5XT0ptIJrJ-6y7yoC4_p3VRR5WiTqtC11f5X19exahmuP19zWNi-7Fp8e0zPlMCKSsmlya4vzcDEor5HKc47pvS-Weu-ijn8QF8jpsgEqf3DLN3D3430EhCjcOdmMJQog54lpAYcOK9UGhTkXwmmAakSjs6mNfS9ZetiJn_QhQ",
         "types" : [
            "train_station",
            "transit_station",
            "point_of_interest",
            "establishment"
         ]
      }
   ],
   "status" : "OK"
}

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.




We know have above JSON as a String and we can use Rest-Assured to do the testing. A basic test would be to check the formatted_address that is returned by the API call. We could do this by specifying JSON path in the path method.

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.

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. train_station

JSON path can be tested at following site:
JSON Path Tester
More information on JSON path can be found at following link:
JSON Path Explanation


Let's have a look at the following example which explains the same.
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 ()  {
    Response res  =given ().param ("query", "Churchgate Station")
    .param ("key", "Xyz")
    .when()
    .get ("/maps/api/place/textsearch/json").
    .then()
    .contentType(ContentType.JSON)
    .extract().
    .path ("results[0].formatted_address");
    
    Assert.assertEquals (res, "Maharshi Karve Rd, Churchgate, Mumbai, Maharashtra 400020");
    
  }
  
}

The above example is same the previous example that we have learned the only difference is that we have used path method in which we have passed the JSON path to extract the formatted_address from the response.

The response is stored in Response variable res and then we have asserted the response using TestNG assertEquals method, which will mark the test case as passed, in this case.

In the next post, we will learn to Install and Configure API Server on the local system.

Update values in Post Data using Json Path in Rest Assured




In the previous post we studied about how to validate json schema in Rest Assured. In this post we will study about how to update values in Post Data (JSON) using Json Path in Rest Assured.


When we have multiple dynamic values in POST Data which will change every time  then we need to read those values from previous request and use those values to update the POST Data (JSON). This is specifically used when the hardcoded values in JSON Data like specific ID's won't work.For example in following POST Data :


{"id":1,"name":"ashwin","surname":"karangutkar","details":{"City":"Mumbai"}}

If I need to change City then Json Path that we will use is details.City.

Before having a glance at code, we will need to import Jayways JsonPathFollowing is the maven import:

<!-- https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path -->
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>

Now let us have a look at Code Snippet:

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;

public class ConvertStringToJson {

 public static void main(String[] args) {

   String jsonString = "{\"id\":1,\"name\":\"ashwin\",\"surname\":\"karangutkar\",\"details\":{\"City\":\"Mumbai\"}}\\";

   Configuration configuration = Configuration.builder().jsonProvider(new JacksonJsonNodeJsonProvider())
   .mappingProvider(new JacksonMappingProvider()).build();

          DocumentContext json = JsonPath.using(configuration).parse(jsonString);
   String jsonPath = "details.City";
   String newValue = "Pune";
   System.out.println(json.set(jsonPath, newValue).jsonString());

 }
}


In the above code, jsonString is the string that we need to update. We configure the jsonProvider using Configuration builder. Now we pass the configuration object to using method of JsonPath and pass the json string to parse method which will return the parsed JSON.Then we pass the json path of the value that needs to be updated and the new value that we need in post Data to set method, which returns the updated POST (JSON) Data.

Output:

Validate JSON Schema using Rest Assured











JSON Schema is a powerful tool for validating the structure of JSON data or your JSON Response. JSON Schema itself is written in JSON. It is data itself, not a computer program. It’s just a declarative format for “describing the structure of other data”. The JSON document being validated or described we call the instance, and the document containing the description is called the schema.

JSON Schema validation is done to check whether the response received is correct or is structured according to the defined schema for your project. Let's look at an example of JSON Schema validation using Rest Assured. Here we are making use of Google Search API that we studied in Testing GET Requests and their Responses using Rest Assured. I would highly recommend reading previous posts before reading this one.

Lets us create a JSON File where we will define the JSON Schema for our response ( JSON Schema of a Response that we will get when we search for Churchgate Station ).


{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "html_attributions": {
      "type": "array",
      "items": {}
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "formatted_address": {
            "type": "string"
          },
          "geometry": {
            "type": "object",
            "properties": {
              "location": {
                "type": "object",
                "properties": {
                  "lat": {
                    "type": "number"
                  },
                  "lng": {
                    "type": "number"
                  }
                },
                "required": [
                  "lat",
                  "lng"
                ]
              },
              "viewport": {
                "type": "object",
                "properties": {
                  "northeast": {
                    "type": "object",
                    "properties": {
                      "lat": {
                        "type": "number"
                      },
                      "lng": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "lat",
                      "lng"
                    ]
                  },
                  "southwest": {
                    "type": "object",
                    "properties": {
                      "lat": {
                        "type": "number"
                      },
                      "lng": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "lat",
                      "lng"
                    ]
                  }
                },
                "required": [
                  "northeast",
                  "southwest"
                ]
              }
            },
            "required": [
              "location",
              "viewport"
            ]
          },
          "icon": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "photos": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "height": {
                  "type": "integer"
                },
                "html_attributions": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "photo_reference": {
                  "type": "string"
                },
                "width": {
                  "type": "integer"
                }
              },
              "required": [
                "height",
                "html_attributions",
                "photo_reference",
                "width"
              ]
            }
          },
          "place_id": {
            "type": "string"
          },
          "rating": {
            "type": "number"
          },
          "reference": {
            "type": "string"
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "formatted_address",
          "geometry",
          "icon",
          "id",
          "name",
          "photos",
          "place_id",
          "rating",
          "reference",
          "types"
        ]
      }
    },
    "status": {
      "type": "string"
    }
  },
  "required": [
    "html_attributions",
    "results",
    "status"
  ]
}

We can also generate JSON Schema for the available response on the following site :

















You need to copy the response in JSON Field and then click on Generate Schema button and the schema will be automatically generated. Copy that schema and paste it in text file and name it as json-schema.json. In your Eclipse project, paste that file under src/test/java as shown below:





















Now lets have a look at an example that will help us to validate JSON schema:

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import io.restassured.RestAssured;
import static io.restassured.RestAssured.*;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;

public class JsonSchemaValidationTest {

  @BeforeClass
   public void setBaseUri () {

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

   @Test
   public void validateJSON () {
     
    given().param ("query", "Churchgate Station")
         .param ("key", "XYZ")
         .when ()
         .get ("/maps/api/place/textsearch/json")
         .then ()
         .body (matchesJsonSchemaInClasspath("json-schema.json"));
    }
}


We will need to import the method matchesJsonScheamInClasspath, so we will add the following import:
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath.

In the setBaseUri method, We are simply setting the default URI to use in all of our tests. Now when we write out a test that calls an API (as we will do in the next step), we don’t have to type in the full address of the API. In this case, the baseUri is https://maps.googleapis.com.

In validateJSON method, Under Given, we will mention the parameters (query and key )while making the API call.When is used for making the API call. Under Then we call Body method which is an option to validate response in which we pass a call to method matchesJsonSchemaInClasspath which will check whether the repsonse receive matches with the schema declared in json-schema.json file

That's all about validating JSON Schema using Using Rest Assured.