Introduction
REST assured is an open source Java library widely used among many of the companies. It provides a domain-specific language (DSL) for writing powerful, maintainable tests for RESTful API.
Developing tool
- IntelliJ IDEA community version would be enough
Framework / Tool / Language
- Maven: It is a build automation tool used primarily for Java project
- Java
- TestNG
Create a maven project via IntelliJ IDEA
File ā New ā Project
Step 2 :
- Give relevant ArtifactId and GroupId and provide the path where the project to be saved.
- You don't need to add any required jar files manually. Maven will import all the relevant JAR files for you. All you have to do is specify the dependencies with the specific versions in the pom file. since we are going to use TestNG and REST Assured we will add them in the pom file.
<dependencies> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>4.1.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> </dependency> <dependency> </dependencies>
- Add following build plugins and properties in pom.xml, In testng file, we define the packages to be executed.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> </plugins> </build>
- Once you have added the dependencies, a popup message will be shown in the bottom saying āImport Changesā. Click on it to import the jars into the Library.

POST request
1. First I have created a Class to provide the base path, port, host, and token to be used for each requests.
package base; import io.restassured.RestAssured; import org.testng.annotations.BeforeClass; public class FunctionalTest { public static String token = "<Token to be used>"; @BeforeClass public static void setup() { String port = System.getProperty("server.port"); if (port == null) { RestAssured.port = Integer.valueOf(<portNo>); } else { RestAssured.port = Integer.valueOf(port); } String basePath = System.getProperty("server.base"); if (basePath == null) { basePath = "</api/test>"; } RestAssured.basePath = basePath; String baseHost = System.getProperty("server.host"); if (baseHost == null) { baseHost = "http://localhost"; } RestAssured.baseURI = baseHost; } }
2. Secondly, I have created a common class called TestRequests.java and extended the FunctionalTest class, in order to use @BeforeClass method and the token.
import base.FunctionalTest; import io.restassured.http.ContentType; import io.restassured.response.Response; import org.apache.commons.lang3.RandomStringUtils; import org.json.simple.JSONObject; import org.json.simple.parser.ParseException; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import static io.restassured.RestAssured.given; public class TestRequests extends FunctionalTest{ String filePath="src/test/java/item/responseofPost.json"; //The location of the path the response to get saved String ItemName_post = "Item1"; String ItemName_put = "Item2"; private static Response response; @DataProvider(name = "data-provider") public Object[][] dataProviderMethod() { return new Object[][]{{"/items"}}; } @Test(dataProvider = "data-provider", priority = 1) public void postReq(String pathName) throws IOException { String payload = "{\"name\":\""+ItemName_post+"\",\"description\":\"Description\"}"; response = given().header("Authorization", "Bearer " + token).contentType(ContentType.JSON) .body(payload) .when() .post(pathName) .then() .statusCode(201) .extract() .response(); System.out.println(response.asString()); FileWriter file = new FileWriter(filePath); file.write(response.asString()); file.flush(); file.close(); } }
- @DataProvider - An important feature provided by TestNG is the testng DataProvider feature. It is a method annotated with @DataProvider, Which returns an array of object, here I have returned the method argument using Data provider.
- @Test - @Test annotation is the important part, where we write code/business logic. If something needs to be automated, that particular code needs to be inserted into the test method. The test method then executes @Test by passing attributes.
- @BeforeClass - It will execute only once before the first test method in that particular class is invoked. You can then initialize or configure set-up for all the conventional test methods
1. In my POST request, I have specified the body request as payload, then passing the body to the endpoint and checking whether the received HTTP status code is 201
2. Once I check the status code I am extracting the response and saving in as a JSON format since I have to use the id for my next request
Sample JSON response of the POST request
{ "name":"Item1", "description":"desc1", "updated_at":"2019-10-21 11:22:38", "created_at":"2019-10-21 11:22:38", "id":9 }
GET Request
- I have written a small method to read the id from the saved JSON response file, which is going to be used in GET request
public Object getItemID() { JSONParser parser = new JSONParser(); Object obj = null; try { obj = parser.parse(new FileReader(filePath)); } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } JSONObject jsonObject = (JSONObject) obj; Object id = jsonObject.get("id"); System.out.println(id); return id; }
Make sure you have added json-simple dependency in the pom file.
<dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1</version> </dependency>
GET the response By ID
@Test(dataProvider = "data-provider", priority = 2) public void getReq(String pathName) { given().header("Authorization", "Bearer " + FunctionalTest.token) .when() .get(pathName + "/" + getItemID()) .then() .statusCode(200).extract().response().prettyPrint(); }
Here I am checking whether the status code is 200 and printing the response on the console.
PUT Request
@Test(dataProvider = "data-provider", priority = 3) public void putReq(String pathName) { String payload = "{\"name\":\""+ItemName_put+"\",\"description\":\"mock\"}"; response = given().header("Authorization", "Bearer " + token) .contentType(ContentType.JSON) .body(payload) .put(pathName + "/" + getItemID()) .then() .statusCode(200).extract().response(); JsonPath jsonPathEvaluater=response.jsonPath(); String nameString=jsonPathEvaluater.get("name"); String desc=jsonPathEvaluater.getString("description"); Assert.assertTrue(nameString.equalsIgnoreCase(ItemName_put)); Assert.assertTrue(desc.equalsIgnoreCase("mock")); }
In PUT request, Iām changing the name and the description.
1. Assertion check on name and description.
2. Checking whether the status code is 200.
DELETE Request
@Test(dataProvider = "data-provider", priority = 5) public void deleteRequestTest(String pathName) { given().header("Authorization", "Bearer " + token) .contentType(ContentType.JSON). delete(pathName + "/" + getItemID()). then() .assertThat().statusCode(204); }
1. Checking whether the status code is 204.
TestNG Report configuration
<dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.2.2</version> </dependency> <dependency> <groupId>org.uncommons</groupId> <artifactId>reportng</artifactId> <version>1.1.4</version> <scope>test</scope> </dependency> <dependency> <groupId>velocity</groupId> <artifactId>velocity-dep</artifactId> <version>1.4</version> </dependency>
Run the tests
- Go to the project path
- Run this command to execute the test cases
: mvn clean test
3. Now it will generate the test cases according to the order of the TestNG priority
4. The generated report can be found in the below mentioned path
target -> surefire -reports ā html
Complete code with CRUD operations
package Item; import base2.FunctionalTest; import io.restassured.http.ContentType; import io.restassured.path.json.JsonPath; import io.restassured.response.Response; import org.apache.commons.lang3.RandomStringUtils; import org.json.simple.JSONObject; import org.json.simple.parser.ParseException; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Ignore; import org.testng.annotations.Test; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import static io.restassured.RestAssured.given; public class ReportRequestTest extends FunctionalTest { String filePath = "src/test/java/item/responseofPost.json"; String ItemName_post = "Item1"; String ItemName_put = "Item2"; String generatedString = RandomStringUtils.randomAlphanumeric(10); private static Response response; @DataProvider(name = "data-provider") public Object[][] dataProviderMethod() { return new Object[][]{{"/items"}}; } @Test(dataProvider = "data-provider", priority = 1) public void postReq(String pathName) throws IOException { String payload = "{\"name\":\"" + ItemName_post + "\",\"description\":\"desc1\"}"; response = given().header("Authorization", "Bearer " + token).contentType(ContentType.JSON) .body(payload) .when() .post(pathName) .then() .statusCode(201) .extract() .response(); System.out.println(response.asString()); FileWriter file = new FileWriter(filePath); file.write(response.asString()); file.flush(); file.close(); } @Test(dataProvider = "data-provider", priority = 2) public void getReq(String pathName) { given().header("Authorization", "Bearer " + FunctionalTest.token) .when() .get(pathName + "/" + getItemID()) .then() .statusCode(200).extract().response().prettyPrint(); } @Test(dataProvider = "data-provider", priority = 3) public void putReq(String pathName) { String payload = "{\"name\":\"" + ItemName_put + "\",\"description\":\"mock\"}"; response = given().header("Authorization", "Bearer " + token) .contentType(ContentType.JSON) .body(payload) .put(pathName + "/" + getItemID()) .then() .statusCode(200).extract().response(); JsonPath jsonPathEvaluater = response.jsonPath(); String nameString = jsonPathEvaluater.get("name"); String desc = jsonPathEvaluater.getString("description"); Assert.assertTrue(nameString.equalsIgnoreCase(ItemName_put)); Assert.assertTrue(desc.equalsIgnoreCase("mock")); } @Test(dataProvider = "data-provider", priority = 4) public void getAll(String pathName) { given().header("Authorization", "Bearer " + token) .when() .get(pathName) .then() .statusCode(200).extract().response().prettyPrint(); } @Test(dataProvider = "data-provider", priority = 5) public void deleteRequestTest(String pathName) { given().header("Authorization", "Bearer " + token) .contentType(ContentType.JSON). delete(pathName + "/" + getItemID()). then() .assertThat().statusCode(204); } public Object getItemID() { JSONParser parser = new JSONParser(); Object obj = null; try { obj = parser.parse(new FileReader(filePath)); } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } JSONObject jsonObject = (JSONObject) obj; Object id = jsonObject.get("id"); System.out.println(id); return id; } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>APITesting</groupId> <artifactId>APITesting</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> </plugins> </build> <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured --> <dependencies> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>4.1.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>3.1.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20080701</version> </dependency> <dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.2.2</version> </dependency> <dependency> <groupId>org.uncommons</groupId> <artifactId>reportng</artifactId> <version>1.1.4</version> <scope>test</scope> </dependency> <dependency> <groupId>velocity</groupId> <artifactId>velocity-dep</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>json-path</artifactId> <version>3.0.0</version> </dependency> </dependencies> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> </project>
Pros
- Dedicated REST API automation framework, supports every HTTP request method, headers, params, built-in assertions
- Open-source
- Maintainable codes
- Supports only Java language
References
http://www.appsdeveloperblog.com/rest-assured-evaluate-json-response-body/
http://rest-assured.io/
Comments
Post a Comment