In this article, we will learn how to perform REST API automation by using Rest Assured, and understand some terms & terminologies related to API testing. First, let’s start with API, which stands for “application programming interface”. It provides the interface to communicate between two applications; irrespective of the programming languages used to develop them 👩💻
Rest Assured is one of the Java libraries which automate REST APIs. It’s not only easy to use but also flexible too, and supports HTTP methods such as GET, POST, PUT, PATCH & DELETE. Apart from supporting BDD (Behavior Driven Development), which has annotations i.e. @Given, @When, @Then, it can also be used with unit testing frameworks such as JUnit & TestNG, and used with ‘Hamcrest’ framework for validation.
📍 Many companies use API to share and make their tool more accessible to various users from external sources. Of course, all these APIs must be tested to ensure their functionality and usability. Another great option for automating APIs and achieving E2E API testing flows is with TestProject‘s free test automation platform. Here’s a great hands-on tutorial to help you get started: Automating End to End API Testing Flows Guide [Test Examples Included]
Table of Contents – REST API Automation From Scratch
- What is REST API
- API testing terms
- HTTP methods
- REST API testing using Rest Assured
- What are Static imports
- Automate POST, GET, PUT, PATCH & DELETE HTTP requests
- Assertions
- Integration of Allure reporting
- Run tests through Maven commands
- Conclusion
What is REST API
Firstly, we need to understand what API is 🔍 It provides a common interface to interact & communicate between two systems. REST API uses the architectural style of an API and has 6 main constraints:
- Client Server
- Stateless
- Cache
- Uniform Interface
- Layered System
- Code On Demand
If an API is developed by using these constraints, then this APIs is REST API 🤗
API testing terms
I will explain the following API terminologies 📖
- Headers
- Path Param
- Query Param
- Payload
- Base URL
- Endpoint
Headers
We use headers so that the client and server will easily understand the request & response well. We can also use headers to pass the Authorization, Content Type, x-api-key, cookie etc. as a key-value pair or a key with multi-values. In the upcoming topics, we will have a look at how to pass header/headers by using the interfaces RequestSpecification and ResponseSpecification:
Path Param
We append the path parameter to the URL and specify it with the curly braces. Generally, we use it to identify the resource uniquely. In simple words, it’s part of the URL itself and specifies as a variable in a URL path 🌐
Example: https://restful-booker.herokuapp.com/booking/{{id}}
Here, {{id}} is referred as a path parameter:
Query Param
By using Query Param, one can get the specific content from the server. For appending, the query parameter goes to the end of the URL by adding ‘?’ and implementing it as a key-value pair.
Example: https://www.google.com/search?q=ApiAutomation
One can also specify the multiple parameters at the API endpoint and separate each parameter by the ‘&’ special character.
Example: https://example.com/booking?category=science&chapeter=thermodynamics
Payload
In simple words, Payload or request body is used to send the data to the server while using the POST, PUT, PATCH request. Request body parameters are included in the request body in the key-value pair as a JSON. We can send Payload as a String, Object, through JSON file, Byte Array:
Base URL & Endpoints
It is one of the base URLs through which the endpoint paths are appended. In simple words, it’s a base address for the specific API. Whereas Endpoints play a vital role which represents the point of entry in an API.
Example: https://restful-booker.herokuapp.com
HTTP methods
These are the 5 HTTP methods:
- GET: to read or retrieve the data
- POST: to create a new resource
- PUT: to update the record
- PATCH: to modify the record but not the complete resource
- DELETE: to delete a resource
We are using one of the open-source “Restful Booker” REST APIs. It has amazing detailed API documentation that has a description of each and every API and has the information of headers, parameters, request body, response body, success message, status code, etc.
REST API testing using Rest Assured
To test REST APIs, we use Rest Assured Java libraries which integrate with Maven. Apart from the fact that it supports the HTTPS methods (i.e., GET, POST, PUT etc.), it validates the response of the requests.
What are Static imports
Static imports reduce the boilerplate code. We use them because of the class name. By importing Static, one can read the code effectively and more understandable:
- import Static io.restassured.*;
- import Static org.hamcrest.*;
Example of Static imports: given().get().getStatusCode();
Example of Non-Static imports: RestAssured.given().get().getStatusCode();
Automate POST, GET, PUT, PATCH & DELETE HTTP requests
We are following the BDD pattern or builder pattern which have- given, when & then statements:
- given() – where we are setting up the Base URI, headers, Path Param, Content Type & Request Body(Payload)
- when() – where we have to mention which HTTP request to hit: GET, POST, PUT, PATCH or DELETE
- then() – where we are validating the response code, response message, response headers, response body, etc.
Automate POST request
Here we are getting the ‘auth token’ in the response by using the POST request. Auth token is nothing but authorizing the user to access the resource. In the below example, we are using the response interface to extract the response, and followed by using jsonPath() we are getting the values from the object as a string (getString()). In the response body, it will return the token which needs the POST, PUT & PATCH request:
Automate GET request
We are automating the GET request to fetch all the booking ids, extract the response, and print the booking ID at 0th index:
Automate PUT request
PUT request is used for replacing the resource entirely. We are updating the record by using PUT as HTTP method and print all the logs of request & response. Here, we are passing the Payload as a string to the body() method in which we are updating the ‘firstname’ and ‘lastname’ in the given Payload:
Automate PATCH request
PATCH request is the correct choice to update the record partially instead of updating the entire resource. We are modifying the record partially by using PATCH HTTP request to update only the ‘firstname’ & ‘lastname’ and followed by validating the status code as ‘200’:
Automate DELETE request
We delete the record and validate the response code as ‘201’. By hitting the request the first time, the status code will be ‘201’ along with a response message. If we hit the same request again it will return ‘405’ as Method Not Allowed:
Assertions
Validate status code
We are validating the status code as ‘200’ of GET request. By using statusCode(), one can easily validate the status code which takes an integer as input & validating against the response code. It will give an assertion error i.e. “java.lang.AssertionError:”, if the status code is not matching with the expected one and then the test will fail ❌
Assert response body
We are validating the response body with the help of body() method. By using the body() method, we are passing the three parameters i.e. ‘firstname’, ‘lastname’ & ‘totalprice’. Here, “booking .firstname” is the path to the field which we want to validate, followed by using “org.hamcrest.CoreMatchers.equalTo()” method to validate the expected value:
Extracting a single field & validating it using Hamcrest
We are extracting the single field from the response in a variable “bookingID” and get the booking id of the 0th index . Below we are performing assert using Hamcrest [assertThat() method] & TestNG [Assert.assertEquals() method]:
Request specification
Request specification is one of the interfaces that we use to reduce the boilerplate code in each and every request. We reuse the code and define baseUri, Content Type, Header and even log in beforeClass(). In the below picture, we can see the baseURI, Content Type, headers & log keep repeating in each request. To avoid that, the “Request specification” interface comes into the picture:
Response specification
Response specification is also an interface. We define the same way all the similar methods in one method which includes Content Type, log, assert status code:
Request specification builder
RequestSpecBuilder is one of the classes which contain different methods to set i.e. addCookie, addMultiPart etc. This is an alternative way to create the request specification using RequestSpecBuilder (class). Here, we are setting the baseURI, headers, Content Type etc in the same way which we did in the request specification above 🔝 After adding all the required details, we have to use the ‘build()’ method so that we can get the reference of request specification:
Response specification builder
ResponseSpecBuilder is one of the classes which contain different methods to set expectBody, expectCookie,expectHeaders etc. By using the ‘ResponseSpecBuilder’ class, we are setting the status code, Content Type, logs for all the requests in a beforeClass() and followed by adding the ‘build()’ method so that we can get the reference of response specification:
Send as a file- We are sending the Payload from a file to the request body. Previously we have hardcoded the Payload & pass it as a string:
Create file class object and pass the relative path .json file as an argument in the file’s default constructor:
Send JSON Object as Map- HashMap is one of the data structures that stores the data as a key-value pair, so it is good to send JSON object as HashMap. In the below example, we are sending the JSON object as a map to the request body:
Expected error – To convert the hash map into JSON object, we have to add the Jackson(data bind) library.
Error: java.lang.IllegalStateException: Cannot serialize object because no JSON serializer found in classpath. Please put Jackson(Databind):
JSON Schema validation- In simple words, JSON Schema describes the data format/types i.e. boolean, int, string etc used by the developer while creating the APIs. Moreover, it is not only used to validate data through automation testing but also provides clear human & machine-readable data.
For automating the JSON Schema validation, we have to use the “matchesJsonSchemaInClasspath” method. We also need to pass the name of the JSON file and keep that file under the class path. To validate the JSON Schema, we have to add the JSON Schema Validator library in pom.xml:
Integration of Allure reporting
To get integrated allure reporting, we first have to install:
- Install Allure on windows/mac
- Allure TestNG dependency
- Allure Rest Assured dependency
- Add property aspectj.version in pom.xml
- Add Maven surefire plugin
If you are using IntelliJ as IDE, open terminal or open CMD by win + R and paste the following command: allure serve allure-results. It will generate an HTML report and open it into a browser 📊
Run tests through Maven commands
For running the tests, we first have to open a command prompt or in IntelliJ, click on the terminal tab and run the command: mvn clean test
Conclusion
Rest Assured is one of the well known Java-based libraries which is used extensively to automate REST APIs. By using these libraries, you can implement things in more than one form. For example, we either go with Hamcrest or TestNG Assert for assertions.
This was my guide to REST API automation and some important API testing terms 🧐 Enjoy!