Rest Assured Framework | Test Automation Framework

Rest Assured Framework

Hi All! Today we will see a basic Rest Assured Framework that you can scale further for big projects. The framework is developed using Java. 

Before starting with the Framework lets checkout the basics that we should know in order to move further. Don’t worry it will be just a refresher, not a detailed one.


What is Rest API and how do we test it?

REST stands for REpresentational State Transfer. It is an architectural style for designing Web services(?).

Web services are pieces of code in a remote machine that is platform-independent (can be executed from any machine). Web Services are used to fetch data from the database and provide it to the client.

Look at the figure below :

Client server-model
Author: Seobility


We have a Server where we have our Rest API services and Database

We have a Client.

Client request data from the Server and Server fetches data from the Database and responds with the data

Remember: Client can be anything from a mobile to a desktop.


API testing is nothing but validating the responses sent by the server.


Rest Api Response Validation


Don’t worry we will go through these with RestAssured example.


Why Rest Assured?

Rest assured is a Java Library that is becoming very famous in the market for performing Rest API Automation. It provides a rich set of powerful APIs, making it way easier to work with Rest APIs.

rest assured features
 

Finally, Let's get started with our Rest Assured Framework Tutorial.

 

Following setup should be done on your machine before we proceed. I am not going to go through all of these since I will go old by then. I will provide links for these steps 

  1. Download Eclipse EE 

  2. Install Java  

  3. Install Maven 

  4. Setup TestNG


Let's start then,

Create a new Maven project

Create new maven project
 


We would require the following dependencies to work with Rest Assured.

Copy them inside your pom.xml file.


RestAssured Dependency

 <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->  
 <dependency>  
   <groupId>io.rest-assured</groupId>  
   <artifactId>rest-assured</artifactId>  
   <version>4.3.0</version>  
   <scope>test</scope>  
 </dependency>   


TestNG Dependency

 <!-- https://mvnrepository.com/artifact/org.testng/testng -->  
 <dependency>  
   <groupId>org.testng</groupId>  
   <artifactId>testng</artifactId>  
   <version>7.1.0</version>  
   <scope>test</scope>  
 </dependency>  


Java Hamcrest Library

 <!-- https://mvnrepository.com/artifact/org.hamcrest/java-hamcrest -->  
 <dependency>  
   <groupId>org.hamcrest</groupId>  
   <artifactId>java-hamcrest</artifactId>  
   <version>2.0.0.0</version>  
   <scope>test</scope>  
 </dependency>  


Now create three packages in src/test/java

 

We will return to this in a minute!


Methods used in Rest Assured

We will cover this framework in BDD(Behaviour Driven Development) style.

And Rest Assured makes it easy to work with BDD since it gives us built-in methods for it. Let’s check out these methods :

given():  We set headers, cookies, parameters & authorization headers for our requests here.

when():  We use HTTP verbs POST, PUT, DELETE, GET to send requests here.

then():    Validating the responses received from the server.

 

Clear? Yes?

 

Setting Config files for different environments

Rest Assured Automation Framework will be useless if we run it on a single environment because in real-time APIs are deployed to different environments. Let me tell you different test environments that we have in my company, so there are three :

1.       DEV - Development Environment

2.       INT - Integration Environment

3.       STG - Staging Environment


We have different URLs for these three environments and properties specific to the environments like port, auth tokens, etc. And this will be the base for our Automation Framework.

 

I will create three different property/config files for these three environments. That’s what you have to do in the root of your project.


config file location
 


And define two properties inside each file:

dev environment config file
integration environment config file
staging environment config file


We'll use a free jsonplaceholder API (Warning: API is not consistent, you might get errors sometimes.)

And single we have only one URL we will add this in all the three files.

But in a real scenario, we'll have different URLs for different environments.


Starting up with our coding part

Now in our com.utilities class, we will define a BaseClass.java file where we will set baseURI for Rest Assured by fetching it from our above properties file with the help of parameter passed from Maven Command line(We will see it later).


The base URI will be set depending upon the environment we will pass from the command line.

For Example : mvn test -Denv=INT (will run the tests in INT environment)


1:  //BaseClass.java  
2:  package com.utilities;  
3:  import java.io.File;  
4:  import java.io.FileInputStream;  
5:  import java.io.FileNotFoundException;  
6:  import java.io.IOException;  
7:  import java.util.Properties;  
8:  import org.apache.log4j.Logger;  
9:  import org.apache.log4j.PropertyConfigurator;  
10:  import org.testng.annotations.BeforeSuite;  
11:  import org.testng.annotations.BeforeTest;  
12:  import org.testng.annotations.Optional;  
13:  import org.testng.annotations.Test;  
14:  import com.testcases.PostsTest;  
15:  import groovyjarjarpicocli.CommandLine.Parameters;  
16:  import io.restassured.RestAssured;  
17:  public class BaseClass {  
18:       public String url;  
19:       String info;  
20:       public Logger LOGGER;  
21:       public Properties prop = new Properties();  
22:       @org.testng.annotations.Parameters({"env"})  
23:       @BeforeTest()  
24:       public void initialize(String environment){  
25:            try {  
26:                 String rootPath = System.getProperty("user.dir");  
27:                 PropertyConfigurator.configure(rootPath + "/log4j.properties");  
28:                 LOGGER = Logger.getLogger(BaseClass.class);       
29:                 if(environment.equals("DEV")) {  
30:                      prop.load(new FileInputStream(new File(rootPath + "/DEVENV.properties")));  
31:                 }else if(environment.equals("INT")) {  
32:                      prop.load(new FileInputStream(new File(rootPath + "/INTENV.properties")));  
33:                 }else if(environment.equals("STG")) {  
34:                      prop.load(new FileInputStream(new File(rootPath + "/STGENV.properties")));  
35:                 }  
36:                 url = prop.getProperty("url");  
37:                 info = prop.getProperty("info");  
38:                 System.out.println("===================================");  
39:                 System.out.println("Info --- "+info);  
40:                 System.out.println("===================================");  
41:                 RestAssured.baseURI = url;  
42:            }catch(FileNotFoundException f) {  
43:            }catch(IOException io) {  
44:            }  
45:       }  
46:  }  

 

The below line will receive parameter which we will pass from Maven Command line/Jenkins(If you want to use it for CI/CD) 

@org.testng.annotations.Parameters({"env"})

 

Below code checks the env parameter that we passed from command line and loads a respective config file

 if(environment.equals("DEV")) {  
      prop.load(new FileInputStream(new File(rootPath + "/DEVENV.properties")));  
 }else if(environment.equals("INT")) {  
      prop.load(new FileInputStream(new File(rootPath + "/INTENV.properties")));  
 }else if(environment.equals("STG")) {  
      prop.load(new FileInputStream(new File(rootPath + "/STGENV.properties")));  
 }  
 url = prop.getProperty("url");  
 info = prop.getProperty("info");  

 

And this code sets up our base URI.

RestAssured.baseURI = url;


Now Create a Post.java file in com.models, I will tell you later why?

1:  //Post.java  
2:  package com.models;  
3:  public class Post {  
4:       public int userId;  
5:       public int id;  
6:       public String title;  
7:       public String body;  
8:       public int getUserId() {  
9:            return userId;  
10:       }  
11:       public void setUserId(int userId) {  
12:            this.userId = userId;  
13:       }  
14:       public int getId() {  
15:            return id;  
16:       }  
17:       public void setId(int id) {  
18:            this.id = id;  
19:       }  
20:       public String getTitle() {  
21:            return title;  
22:       }  
23:       public void setTitle(String title) {  
24:            this.title = title;  
25:       }  
26:       public String getBody() {  
27:            return body;  
28:       }  
29:       public void setBody(String body) {  
30:            this.body = body;  
31:       }  
32:  }  


There are a number of fake Rest APIs on jsonplaceholder website, but we will use /posts API.

URL : https://jsonplaceholder.typicode.com/posts


Now let's create our test cases in package com.testcases defined earlier.

Create a PostsTest.java file under package com.testCases.

 

1:  //PostsTest.java  
2:  package com.testcases;  
3:  import java.io.FileInputStream;  
4:  import java.io.FileNotFoundException;  
5:  import java.io.IOException;  
6:  import java.util.Properties;  
7:  import static org.hamcrest.Matchers.*;  
8:  import org.apache.log4j.Logger;  
9:  import org.apache.log4j.PropertyConfigurator;  
10:  import org.testng.Assert;  
11:  import org.testng.annotations.BeforeClass;  
12:  import org.testng.annotations.Test;  
13:  import com.models.Post;  
14:  import com.utilities.BaseClass;  
15:  import static io.restassured.RestAssured.*;  
16:  import io.restassured.RestAssured;  
17:  import io.restassured.http.ContentType;  
18:  import io.restassured.path.json.JsonPath;  
19:  import io.restassured.response.Response;  
20:  public class PostsTest extends BaseClass {  
21:       int postId = 1;  
22:       @Test(priority = 1)  
23:       void createNewPost() {  
24:            Post newPost = new Post();  
25:            newPost.setUserId(1);  
26:            newPost.setTitle("new title");  
27:            newPost.setBody("new body");  
28:            Post postedPost =   
29:            given()  
30:                 .contentType(ContentType.JSON)  
31:                 .body(newPost)  
32:            .when()  
33:                 .post("/posts")  
34:            .then()  
35:                 .assertThat()  
36:                 .statusCode(201)  
37:                 .log().all()  
38:                 .extract()  
39:                 .as(Post.class);  
40:            System.out.println("Posted Post Title : "+postedPost.title);  
41:            postId = postedPost.userId;  
42:            Assert.assertEquals(postedPost.title, "new title");  
43:       }  
44:       @Test(priority = 2)  
45:       void getSinglePost() {  
46:            given()  
47:            .when()  
48:                 .get("/posts/"+postId)  
49:            .then()  
50:                 .assertThat()  
51:                 .body("id", equalTo(postId))  
52:  //               .body("id", equalTo(postId), "title", equalTo("new title")  
53:                 .log().all(true);  
54:       }  
55:  }  

We will be having just one class and these two methods since this article will become way too long. You can add more if you understand the basics.

 

Now look at the code below. This is why we added Post.java class previously

 Post newPost = new Post();  
 newPost.setUserId(1);  
 newPost.setTitle("new title");  
 newPost.setBody("new body");  

This is how we send our body in a post request

Another alternative is to use Java HashMap but I like this better.

 

Now you will have to add a dependency in pom.xml

 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->  
 <dependency> <!-- Convert java onject to json -->  
       <groupId>com.fasterxml.jackson.core</groupId>  
       <artifactId>jackson-databind</artifactId>  
       <version>2.10.2</version>  
  </dependency>  

        

This dependency will convert our Java object to JSON format.


given()

 .contentType(ContentType.JSON)

 .body(newPost)

 

You see we are setting the body with our newPost object but how will this object be sent across to the server.

Because the only format that is used for transferring data is JSON/XML.


Finally, convert your project to TestNG by:

Right-clicking on your project root folder -> TestNG -> Convert to TestNG.

 


This is the final step of our framework.

Now for running the tests open the command prompt from the folder where your project is.

 

And run command

mvn test –Denv=INT

 

maven command line

 

You can use any environment (DEV, INT, STG).


That is it! I want you to try out this Rest Assured Framework once.

You can further integrate it with Github, Jenkins, reports, or logging(Log4j).

If you want the Git and Jenkins integration or the code of the framework, comment down below

If you need I will write another article for it – maybe a Second part of this framework