Users Online
· Members Online: 0
· Total Members: 188
· Newest Member: meenachowdary055
Forum Threads
Latest Articles
Articles Hierarchy
Rest Assured Tutorial for REST API Automation Testing
What is API Documentation, and Why It Matters?
Automation has a crucial position in this technology-centric world. Faster and short releases are in vogue. In addition to that, the agile development method has gained a foothold in the software industry. There has been a remarkable change in the way we develop software automation tests in agile.
Rising Need For API Testing
The old practice of having only the GUI tests for automation does not exist anymore. Moreover, the problems in software testing with the GUI tests are several. To enumerate a few:
- The tests may fail frequently owing to frequent changes in the UI
- Additional maintenance and refactoring efforts associated with flaky tests
- Moreover, its a time-consuming test process and has slower feedback.
- It requires a large number of initiatives in terms of maintainability and stability.
In a two week aligned sprint, it gets altogether challenging to have a UI ready and test it simultaneously for test coverage results. Unlike the GUI tests, the API testing doesn't rely on the UI. It becomes much more comfortable to conjoin/ integrate them under Agile Development. Additionally, it can be brought in much earlier at the development stage. The increasing/ rising trend of API Testing underlines this further.
An API abstracts the implementation layer, exposing only the objects needed by the developer. It consists of REST methods. Moreover, these REST methods fetch, manipulate, and delete the data in the application's database. We need to familiarize ourselves with the workings of REST API basics. Please go through the REST API tutorials to be acquainted with those.
Once we have familiarised ourselves with the REST API basics, it is time to learn to test the REST APIs. To test a REST API, we must understand the interface of the API. This includes:
- The operations we can perform using the API
- Structure of the requests
- Structure of responses
Therefore, an essential step in that direction would be to look at the API Documentations. In this article, we are going to cover:-
- Why do we need an API Documentation?
- What is an API Documentation?
- How to use API Document?
- What are the various types of tests for API?
Let us first understand the benefits of API Documentation.
Why do we need an API Documentation?
Documentation of any technology has a direct impact on the adoption and its usage. Without the knowledge of the tool, no one would know how to use it. Moreover, there are other advantages to it as listed below:
- It provides a quick and easy guide for API consumption.
- Reduces user frustrations.
- Demonstrates useful functions.
- Saves support costs and time.
These are some of the benefits of API documentation. Let us learn and understand what all consists of an API Documentation.
What is an API Documentation?
API documents are similar to a reference manual. It talks about the necessary information of an API, in terms of,
Description of Resources
The data returned by the API are resources. Various endpoints can be used to access resources. Under the same resource, an API will have several routes grouped. Resources and endpoint descriptions are generally short and precise. Additionally, the user guide contains a piece of more detailed information.
Methods and their endpoints
The endpoint is an essential part of the API documentation. The developers implement it to make the requests. Endpoints indicate ways to access resources. The methods indicate permissible interactions such as GET, PUT, POST, or DELETE with the resource. Endpoints, similar to overall resource descriptions, as well have short brief descriptions. The endpoint shows the end path of a resource. It does not include a common base path to all endpoints.
Consider a sample APIs collection available to us as TOOLSQA - Bookstore API provided by TOOLSQA. Please navigate to the URL. Consequently, once the page opens, we will see this:
In the above image:
Bookstore and Account are resources available in Bookstore API
An HTTP method acts as a verb. The listed verbs POST, GET, DELETE in the above image are some of the examples. Moreover, there are others as well, like PUT, PATCH, OPTION, etc.
The routes in the above image are:
- /Account/v1/Authorized
- /Account/v1/GenerateToken
- /Account/v1/User
- /Account/v1/User/{GUID}
- /Account/v1/User/{UserId}
- /BookStore/v1/Books
- /BookStore/v1/Books
The routes are following the method to form an endpoint. Example, GET /Account/v1/Authorized.
Note: We have a very few endpoints listed here in the sample bookstore API URL. But in actual projects, the list of endpoints can be much large.
For an endpoint, the full resource URL needn't be listed in an API document. So, in our example, GET /Account/v1/Authorized is listed instead of GET http://bookstore.toolsqa.com/Account/v1/Authorized
It is done with the thought to make the users focus on the path. Additionally, the user guide provides the full resource URL and the needed authorization in the introductory section.
Parameters used
Parameters are the options that control the resource. There are four kinds of parameters:
- Header parameter: As the name suggests, these are the parameters passed into the request headers. They are generally related to the authorization and included under a separate section of authorization requirements for standard header parameters. Additionally, in the case of unique parameters passed in the headers, they are documented with the respective endpoint.
- Path parameter: Path parameters are part of the endpoint. They are not optional. We usually write them along with curly braces. For example, /Account/v1/User/{UserId} Here, {UserId} is the path parameter.
- Query parameter: They are attached to the URL end. Additionally, the Query Parameter is appended to the URL after adding '?' at the end of the URL. You can read more in the Query Parameter tutorial.
- Request body parameters: In a POST request, several times, a JSON object is submitted in the request body. Moreover, it is a list of key-value pairs.
Example:
{
"username": "TOOLSQA-Test",
"password": "Test@@123"
}
Examples of Requests and Responses
In the above example, we passed the username and password as request body parameters. We got a 200 status code response along with the response body for the POST request of the endpoint /Account/v1/GenerateToken, we sent.
Alongside, if you notice the highlighted section, it is that of a curl command.
curl -X POST "https://bookstore.toolsqa.com/Account/v1/GenerateToken" -H "accept: application/json" -H "authorization: Basic VE9PTFNRQS1UZXN0OlRlc3RAQDEyMw==" -H "Content-Type: application/json" -d "{ \"userName\": \"TOOLSQA-Test\", \"password\": \"Test@@123\"}"
We follow Curl format for several reasons:
- Firstly, curl is independent of the programming language.
- Secondly, it consists of the request header information.
- Additionally, it displays the Request method.
Thus, we have understood the contents of a typical API document. An API document may contain additional information. But the above part of the tutorial gives us a general idea of everything included under an API document. Subsequently, in our next stage, we will learn the usage of an API document.
How to use an API Document?
To understand the use of Swagger API documentation, we will use the same Bookstore API used previously. It consists of a sandbox environment that tests the APIs on the documentation.
Navigate to the Bookstore API. You will see the following:
The grouping of endpoints is as follows:
- Account
- BookStore
Some of those API Endpoints listed below build our End to End Rest API Framework. Please try these examples once you have learned to use the API document at the end of this section.
HTTP VERB | Route | PURPOSE |
---|---|---|
POST | /Account/v1/GenerateToken | To generate token as the endpoint name suggests |
GET | /Account/v1/User | To create a userId with associated user |
GET | /BookStore/v1/Books | To fetch a list of books |
POST | /BookStore/v1/Books | To add a book associated with the user |
DELETE | /BookStore/v1/Books | To remove a book |
GET | /Account/v1/User/{UserId} | To get a list of books associated with userId |
We listed some of the APIs below from the bookstore API. They will help us to understand the requests and their response bodies using Swagger.
- To Create User
- To Generate Token with the created User
API Documentation - Create User - POST
Before we begin exploring the APIs, we need to create a user with a username and password. Subsequently, add a desired username and password under Book Store Credentials.
Note: Please choose your username and password, and once created, remember to use the same username and password for all the tests. For example, throughout we will be using TOOLSQA-Test as username and Test@@123 as password.
Now, let's try and create a userID using the POST Request for User.
Make a request
- First, Expand the POST method for the endpoint under Account: /Account/v1/User
- Second, click the Try it out button. The Request Body field gets editable.
- Third, add the username and password. You have added now, as indicated in the below screenshot. After that, select the parameter content type as application/json. Click on the Execute button.
- Finally, Swagger submits the request. It shows the curl that was submitted. The Response, for the request, is observed in the response section.
Note: Please note down the userID. You will need it for other APIs in the request body.
Explanation: We passed a POST Request with username and password in JSON format. We got a 201 status code along with userID, and books associated with the respective username in the Response body. It explains that our request was successfully sent over the server, as you can see in the above image under Description. Additionally, Swagger's implementation is simple and useful. It provides an interactive experience to send a request and receive a response for APIs.
As software professionals, we need to understand the underpinnings on which great software builds. One of the many means is to try and test them over in various ways. We familiarized ourselves with the API Documentation. Additionally, Swagger provided us with the means to test it on Swagger UI itself.
API Documentation - Generate Token - POST
Now that we have created a user in our previous response let's try and create a token using the POST Request for User.
Explanation: We sent our request with the body containing a username and password in the application/json format. When we click the Execute button, we got a 200 status code. Additionally, we also got a response body with the token, expires, status, and result fields. In the next section, we will understand the context of API tests and study its various types.
What are the various types of API Tests?
Before we commence actual testing of the APIs, we need to compile associated information of the APIs. The context in which we carry out testing is essential because it drives our testing efforts.
Below is a non-comprehensive list of the information we can seek before we start testing the APIs:
- Expected response code from a successful request
- Expected response code from an unsuccessful request
- Fields to be validated
- Parameters required
- Error handling of unsuccessful requests
- HTTP verbs that we can use with the endpoints
Let us understand, under which all categories the API tests can be divided. It is not to say that we have enlisted a comprehensive list; there could be more types we can add to the list. But more or less, the API tests fall under one of the categories mentioned below.
- Validation Testing: It forms one of the last segments in the software development process. It caters to the testing explicitly done to assess the product; its behavior, and its efficiency. The API is examined for correctness in implementation as per the expectations. Additionally, the API is also verified based on pre-established agreed-upon criteria such as the delivery of specific end goals, integration with the specified environment. In addition to that, the testing of API's behavior to access the correct data happens as a part of Validation testing.
- Functional Testing: This is one of the broader types of testing. It aims to test specified functions. While testing the APIs for functional testing, the assessment of the responses received happens against expected responses in terms of passing parameters. Additionally, the error handling for unsuccessful requests and invalid responses too are under consideration under these tests. The boundary cases, along with regular tests, fall under the scope of these tests.
- UI Testing: UI Tests tend to be more specific. These tests assess the user interface against the APIs and their constituent parts. Additionally, the tests are more generalized with a focus on the API health; it's usability as well as compatibility of the front end and back end.
- Load Testing: This test is for the functionality and performance of the APIs under load. The API undergoes theoretical regular traffic. The test results form the baseline to conduct further load testing. Additionally, the testing also includes subjecting the API to maximum possible traffic to test the behavior of the API under full loads. APIs undergo overloading tests. In this test, the verification of the API performance and error handling conditions during failure happens.
- Error Detection: The tests for APIs, which include the monitoring, inducing execution errors, sending invalid requests, detecting operational leaks, etc. fall under this category. The introduction of known failure scenarios in the APIs happens. The testing of these APIs happens to ensure that the errors are detected, handled as well as routed.
- API Security tests: Specific tests verify the APIs performance for vulnerabilities from external threats. Security testing, Penetration testing, and Fuzz testing are some of them. For example, Security testing involves validation of the APIs in terms of security requirements. Additionally, these security requirements could be related to permissions, authorizations, authentications, etc. An authorized attack launches against the system as a part of Penetration testing. It evaluates the security of the API. A full-scale assessment report of strengths and weaknesses of the APIs is the deliverable issued after such a test. In Fuzz testing, evaluation of API behavior happens. It is subjected to unexpected, invalid, and random data of enormous size. Following this, the crashes, built-in assertions, and memory leaks are known.
- Integration testing: The Integration tests focus on API communication with another module APIs.
- Reliability testing: The API should display a prompt response for different configurations. It also looks for a response data structure as a part of testing.
To conclude, in this post, we have got an understanding of API documentation. We learned to use the Swagger API document. Additionally, we acquainted ourselves with types of API testing.
In further posts, we will learn to build REST API Automation Framework around the API tests. Try out using the API document as guided above and reach out for your valuable feedback.
In this tutorial, we will learn to write REST API End to End Test.
We carefully laid the foundations of our API automation framework components. We will be heavily relying on our previous knowledge gained for Rest Assured, Cucumber as well as Maven. Subsequently, these will form the base over which we will build our API Automation Framework. I will be referring to them every once in a while and adding useful links as we need more of them. It's advisable to clear up the basics by going through the tutorials:
In our automation framework, we will automate an End to End business flow of a use case. Additionally, it will help to demonstrate the right examples of framework components and explain their usages. Besides, our understanding of building the Rest Assured API Automation Framework from scratch will improve as we go about this tutorial.
Many-a-times we are involved in getting ready-made frameworks that are built by Senior Test Architects or Software Developers. Understanding the underlying principles and design ideas are crucial to develop our skills as software engineers.
Prerequisites for REST API End to End Test
- Java Setup
- IDE Setup
- Maven Setup
- Create a maven project
- Add Rest Assured Dependencies
- Setup Maven Compiler Plugin
- Create a user for the test
Step 1 - Java Setup
We will use Java as our language, for writing our REST API automation framework based on the Rest Assured library. For this, we will need to install Java on our machines if not previously installed. Likewise, please follow through the tutorial to install Java as our first prerequisite.
Step 2 - IDE Setup
As we will be working with Java, we will need an editor to use for Java. Eclipse, IntelliJ, Net Beans, and several others are popular IDEs you can choose to work. Furthermore, a tutorial on installing Eclipse on Windows and for Mac users exists to ease the process. Please pick an IDE you are comfortable working with and get going.
Step 3 - Maven Setup
Build tools enable us to create executable applications from the source code. They help to automate and script everyday activities like downloading dependencies, compiling, running our tests, and deployments. Moreover, we will use the Maven build tool for our End To End Scenarios. We have created a tutorial explaining the installation of Maven on Windows. Additionally, please install Maven, if not previously installed as we would need it.
Step 4: Create a New Maven Project
Eclipse operates with workspaces, folders, and spaces where you add your projects. Software Teams use different approaches for workspaces and project structures but try to follow and stick with the default structure.
In addition to this, to create a new maven project, please follow our article Steps to create a New Maven Project. Just to make sure that you specify below values to Maven Archetype Parameters:
- Group ID: ToolsQA
- Artifact ID: API TestingFramework
Note: You can have any names as Group ID and Artifact ID. However, for the ease of this tutorial, it is better to keep the same naming conventions across the project. Also, it helps in resolving issues while copying pasting the code.
Step 5 - Add Rest Assured Dependencies
We will add Rest Assured Dependencies to our project through the pom.xml file. To add the required dependencies, go to Rest Assured Maven Repository. Then, select the latest dependency. Copy-paste it in the project pom.xml file.
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
Note: As of Feb'2020, the latest rest-assured version is 4.2.0.
We should add the dependency tag within the dependencies tag, like below.
<dependencies>
<dependency>Project Dependency</dependency>
</dependencies>
Further, we will be using JUnit Dependency. So please add that dependency in the pom.xml.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
Note: As of Feb'2020, the latest JUnit version is 4.13. Always use the latest Junit version.
Step 6: Setup Maven Compiler Plugin
The Compiler Plugin compiles the sources of the project. Regardless of the JDK you run Maven with, the default source setting is 1.5, and the default target setting is 1.5. Additionally, to change the defaults, please set the source and target as described in Setting the –source and –target of the Java Compiler.
Below you can find the maven-compiler-plugin settings:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
The complete POM would turn out to be likewise:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ToolsQA</groupId>
<artifactId>RestAssured_APITests</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 7: Create an Authorized user for the test
Finally, before we begin automation of our tests, the last piece is remaining. It is of creating an authorized user. We need to create a user that will use our End to End automation tests. We have learned to create a user in our previous tutorial under the POST Request. The POST Request tutorial explains how a POST Request method sends data to the server.
S
@Test
public void RegistrationSuccessful() {
RestAssured.baseURI = "https://bookstore.toolsqa.com";
RequestSpecification request = RestAssured.given();
JSONObject requestParams = new JSONObject();
/*I have put a unique username and password as below,
you can enter any as per your liking. */
requestParams.put("UserName", "TOOLSQA-Test");
requestParams.put("Password", "Test@@123");
request.body(requestParams.toJSONString());
Response response = request.post("/Account/v1/User");
Assert.assertEquals(response.getStatusCode(), 201);
// We will need the userID in the response body for our tests, please save it in a local variable
String userID = response.getBody().jsonPath().getString("userID");
}
Write REST API End to End Test:
Let's consider this scenario:-
Test Scenario: As an existing authorized user, I retrieve a list of books available for me in the library. I will assign a book to myself and later on return it.
We will divide the test scenario into below steps for simplicity:
1. Test will start from generating Token for Authorization - First, we have the username and password of a registered user. Using these credentials, we will generate a token. Additionally, we will send this token into the Requests instead of the username and password. The reason we follow this practice is to have specific resources allocated in a time-bound manner. This step involves making a POST Request call in Rest Assured by passing username and password. Kindly follow this POST Request tutorial to learn about how to send a POST Request.
Note: The below-mentioned User won't work, please create your user for practice.
2. Get List of available books in the library - Secondly, it is a GET Request call. It gets us, the list of available books. Visit the GET Request tutorial to understand the logic of how we make a GET Request call in Rest-Assured.
3. Add a book from the list to the user - The third is a POST Request call. We will send the user and book details in the Request.
4. Delete the added book from the list of books - Fourth is a DELETE Request call. We will delete the added book from the list. The DELETE Request tutorial will help you with it.
5. Confirm if the book removal happens successfully - Last but not least, as a verification step, we will verify if the book has got removed from the user. Therefore, we will send user details in a GET Request call to get details of the user.
Create a Test Package & a Test Class
-
Firstly create a New Package by right click on the src/test/java package and select New >> Package. Moreover, give your package a name apiTests and click Finish.
-
Secondly, create a New Class file by right click on the src/test/java package and select New >> Class. Give your test case the correct name in the resulting dialog and click Finish to create the file. Also, to make sure to check the public static void main, as we will be running the test from the same primary method. I have named the class as E2E_Tests, as you can see in the code snippet below.
Write the complete REST API End to End Test
I have written an end to end test encompassing the steps as mentioned above. The example is relatively simple to follow through. Moreover, it involves the use of GET, POST, and DELETE Requests. It will benefit you if you go through the Rest Assured Tutorial at this point if you are not following.
package apiTests;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import io.restassured.RestAssured;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
public class E2E_Tests {
public static void main(String[] args) {
String userID = "9b5f49ab-eea9-45f4-9d66-bcf56a531b85";
String userName = "TOOLSQA-Test";
String password = "Test@@123";
String baseUrl = "https://bookstore.toolsqa.com";
RestAssured.baseURI = baseUrl;
RequestSpecification request = RestAssured.given();
//Step - 1
//Test will start from generating Token for Authorization
request.header("Content-Type", "application/json");
Response response = request.body("{ \"userName\":\"" + userName + "\", \"password\":\"" + password + "\"}")
.post("/Account/v1/GenerateToken");
Assert.assertEquals(response.getStatusCode(), 200);
String jsonString = response.asString();
Assert.assertTrue(jsonString.contains("token"));
//This token will be used in later requests
String token = JsonPath.from(jsonString).get("token");
//Step - 2
// Get Books - No Auth is required for this.
response = request.get("/BookStore/v1/Books");
Assert.assertEquals(response.getStatusCode(), 200);
jsonString = response.asString();
List<Map<String, String>> books = JsonPath.from(jsonString).get("books");
Assert.assertTrue(books.size() > 0);
//This bookId will be used in later requests, to add the book with respective isbn
String bookId = books.get(0).get("isbn");
//Step - 3
// Add a book - with Auth
//The token we had saved in the variable before from response in Step 1,
//we will be passing in the headers for each of the succeeding request
request.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json");
response = request.body("{ \"userId\": \"" + userID + "\", " +
"\"collectionOfIsbns\": [ { \"isbn\": \"" + bookId + "\" } ]}")
.post("/BookStore/v1/Books");
Assert.assertEquals( 201, response.getStatusCode());
//Step - 4
// Delete a book - with Auth
request.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json");
response = request.body("{ \"isbn\": \"" + bookId + "\", \"userId\": \"" + userID + "\"}")
.delete("/BookStore/v1/Book");
Assert.assertEquals(204, response.getStatusCode());
//Step - 5
// Get User
request.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json");
response = request.get("/Account/v1/User/" + userID);
Assert.assertEquals(200, response.getStatusCode());
jsonString = response.asString();
List<Map<String, String>> booksOfUser = JsonPath.from(jsonString).get("books");
Assert.assertEquals(0, booksOfUser.size());
}
}
Note: We added an import statement for JSONpath, import io.restassured.path.json.JsonPath; It will help us to traverse through the specific parts of the JSON. You can read more in the JSONPath article.
Run the REST API Test
Next step, we need to execute the test. Right-click in the test body and select Run As >> Java Application. The test will run, and you'll see the results in the Console. Consequently, the program executes successfully without any error. Just in case you happen to configure the same on IntelliJ IDE, the effect observed will be "Process finished with exit code 0". Additionally, it is another sign signifying that there were no errors and our tests executed successfully.
Note: It is not a UI based test. Moreover, there will not be any visual output to observe the test execution.
Conclusively, in the next tutorial, we will Convert our API tests into Cucumber BDD style. It will further our understanding of the way Cucumber Tests are structured.