RESTful WebServices API Testing [Rest Assured & Karate Framework]
In this article, covering the most popular RESTful Webservices-API test automation frameworks — Rest Assured and Karate framework. Both frameworks are robust, scalable, customizable and easy to write API automated tests in a simpler form when compared to tools such as Postman, Jmeter and Katalon.
API Testing:
API interface represents the Application Programming Interface. It involves a lot of capacities that can be gotten to and executed by another middleware system. Along these lines, it fills in as an interface between various programming systems and sets up their association and information trade.
In the cutting edge advancement world, many web applications are planned dependent on a three-tier design model. These are:
1) Presentation Tier — User Interface (UI)
2) Logic Tier — The business rationale is written right now. It is additionally called the Business Tier. (Programming interface)
3) Data Tier — Here data and information are put away and recovered from a Database. (DB)
In the modern world, many companies, mobile apps, IoT and payment gateways rely on API web services development and testing. When developing new software or application, as a QA it’s in every case great practice, to begin with, API-level testing as opposed to coordinate UI-useful testing. During the API testing, we can cover usefulness, unwavering quality, execution, load and security testing of the endpoints and validate the response.
For Instance:
A user opens a traveling website such as MakeMyTrip https://www.makemytrip.com/ and searches for `Delhi to Bangalore trip`, then MakeMyTrip calls an endpoint to retrieve data using a GET request to AirAsia to fetch a list of flights traveling on passenger selected date and simply displays to the user on UI in a more readable manner.
RESTful Web-Services:
RESTful Web Services are fundamentally REST Architecture based Web Services. In REST Architecture everything is an asset. RESTful web services are lightweight, profoundly adaptable and viable and are easy to used to make APIs for web applications.
Rest-Assured:
So as to test REST APIs, the REST Assured library is robust, scalable, extensible and returns high ROI. REST Assured is a Java DSL for simplifying testing of REST-based services built on top of HTTP Builder. It supports POST, GET, PUT, DELETE, OPTIONS, PATCH, and HEAD requests and can be used to validate and verify the response of these requests. Rest-Assured gives a great deal of features, for example, DSL-like sentence structure, XPath-Validation, Specification Reuse, Authentication, simple document transfers and with those highlights we will deal with automated API testing a lot simpler.
For Selenium with Java testers, Rest-Assured setup is a cakewalk but for manual testers and beginners might take some time to get the concept. It has a gherkin type linguistic structure which is appeared in beneath code. On the other side, if you are from Cucumber-BDD (Behavior Driven Development) background, I believe that you will adore this kind of syntax.
In this article, have used Restful-booker open-source Rest API is a Create Read Update Delete Web API that comes with authentication features and loaded with a bunch of bugs for you to explore.
https://restful-booker.herokuapp.com/apidoc/
Pre-Requisite:
Good to have the core-java experience but it’s not mandatory.
Maven or Gradle to build.
Eclipse of IntelliJ IDEA — IDE.
TestNG or Junit Framework.
Setup:
You can use either Eclipse or IntelliJ IDE for the setup. Create a maven project and add below dependency from the maven central repository to the pom.xml. https://mvnrepository.com/repos/central
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
GET Request:
First, let's start with the GET request. To get all the herokuapp.com booking IDs from the server and validate the response status, then we need to call the below endpoint using positive and negative scenarios.
A GET request has below elements:
URL: This is the location of the resource we retrieve data from the server.
Action: to retrieve data, we use a GET request.
Headers: these are request headers, such as Accept or Content-Type.
HOST: https://restful-booker.herokuapp.com
Path: /booking
- Create a maven project, create a package and add
GetMethods.java
class file - Add a GET request test method
- Validate the status code and body response.
given()
.contentType("application/json")
.when().get(prop.getKey("HOST") + "/booking")
.then()
.statusCode(200)
.body(containsString("bookingid"));
We can test the latency of the server by checking `Response time is less than 2000ms`
Response response = given()
.contentType("application/json")
.when()
.get(prop.getKey("HOST") + "/booking");
long latency = response.getTime();
if (latency > 2000) {
throw new Exception(
"Response Time Failed: Should be Less than 2000L;" + "Actual Response Time: " + latency);
}
When calling the above endpoint for the valid scenario the status should be 200
and response should be as below.
Note: Content-Type should pass as application/json
in headers
HTTP/1.1 200 OK
[
{
"bookingid": 1
},
{
"bookingid": 2
},
{
"bookingid": 3
},
{
"bookingid": 4
}
]
POST Request:
To create a new herokuapp.com booking to the server and store user details in the database then we need to call the below endpoint using positive and negative scenarios and validate the response status.
A POST request has below elements:
URL: This is the location of the resource we retrieve data from the server.
Action: when submitting data, we use the POST request.
Headers: these are request headers, such as Accept or Content-Type.
Body: The body contains the data which we submit as a post request. For example, when submitting a form, form data are sent in the body of the request.
HOST: https://restful-booker.herokuapp.com
Path: /booking
- Create a Post
Methods.java
class file - Add a POST request test method
- Validate the status code and body response.
We can pass the body payload in multiple forms.
Ex: Using params — pass key-value parameters in the below format and can call the endpoint and verify response.
Response response = given()
.contentType("application/json")
.queryParam("firstname", "George")
.queryParam("lastname", "brown")
.queryParam("totalprice", 2000)
.queryParam("depositpaid", false)
.queryParam("additionalneeds", "late checking")
.when()
.post(prop.getKey("apiurl") + "/enquiries");
Ex: Using payload.json file — to save paylaod in json file and call the file in the test script as below. This approach reduces the data duplication and hard-coding of payload.
Payload.json file:
{
"firstname" : "James",
"lastname" : "Brown",
"totalprice" : 1000,
"depositpaid" : true,
"bookingdates" : {
"checkin" : "2020-05-01",
"checkout" : "2020-05-020"
},
"additionalneeds" : "Breakfast",
"additionalneeds" : "Non-Smoking Room"
}
Test Script file:
File payload = new File(System.getProperty("user.dir") + "/src/test/resources/payload.json");Response response = given()
.contentType("application/json")
.body(payload)
.when()
.post(prop.getKey("HOST") + "/booking");
response
.then()
.statusCode(200);
String actual = response.then().contentType(ContentType.JSON).extract().path("booking.firstname");
String expected = "James";
Assert.assertEquals(actual, (expected));
Ex: using Haspmap —
Map<String, String> body = new HashMap<>();
body.put("CountryCode", "MY");
body.put("Page", "1");
body.put("keyword", "mah sing group berhad");
When calling the above endpoint for the valid scenario the status should be 200
and response should be as below.
HTTP/1.1 200 OK
{
"bookingid": 1,
"booking": {
"firstname": "James",
"lastname": "Brown",
"totalprice": 111,
"depositpaid": true,
"bookingdates": {
"checkin": "2018-01-01",
"checkout": "2019-01-01"
},
"additionalneeds": "Breakfast"
}
}
Authentication:
Need authentication? REST Assured provides several authentication mechanisms:
given().auth().basic(username, password).when().get("/secured").then().statusCode(200);given().header("Authorization", KEY).contentType("application/json").body(body).when().post(url)
.getStatusCode();
Other Features:
Rest Assured provides multiple features, for instance, XML handling, JSON schema validation, Cookies, Logging, and Object mapping etc., Please check the user-guide for all features configuration.
https://github.com/rest-assured/rest-assured/wiki/Usage#headers-cookies-status-etc
Execution:
By right-click on GetMethods.java
and Run to execute all get test cases.
or
Using maven, go to project root & run cmmd mvn clean install test
in terminal.
Reports:
By default, TestNG reports will be generated to the target/surefire-reports
folder after execution but, if need custom and advanced reports can use Extent reports.
TestNG Logs:
Karate Framework:
If you want to write scripts in BDD Gherkin style and in a simpler framework with no coding skills then Karate Framework
it is the best option. Karate framework comes with pre-defined functions where we can call the steps in feature file and write tests in seconds
Add Maven Dependencies and start writing API tests in Cucumber format:
<dependencies>
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-apache</artifactId>
<version>${karate.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit4</artifactId>
<version>${karate.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Above GET & POST requests can be written in a simpler form as below.
GET requests:
Feature: GET requests
Background:
* url 'https://restful-booker.herokuapp.com'
* header Accept = 'application/json'
Scenario: check Get all bookings
Given path '/booking'
When method get
Then status 200Scenario: Get request By ID
Given path '/booking/5'
When method get
Then status 200
Post request:
Feature: POST requests
Background:
* url 'https://restful-booker.herokuapp.com'
* header Accept = 'application/json'
Scenario: check Post request
Given path '/booking'
And request {"firstname" : "james", "lastname": "brown", "price": 1000}
When method POST
Then status 200
And def booking = response Given path '/booking/'+booking.id
When method GET
Then status 200
And match $ contains {id:'#(booking.id)',name:'#. (booking.firstname)',price:#(booking.price)}
Summary:
When coming to API testing, there are many tools in the market such as Postman, Jmeter, and Katalon but these tools are good for manual testing, comes in limited features and not customizable.
In simple terms, for beginners, code-less automation, non-technical and manual testing purpose tools like Postman, Jmeter, Katalon, and TestProject are good for API testing automation. But for bigger and advanced projects we need scalable, extensible and robust frameworks such as Rest-Assured, Frisby.js, RestSharp, Chakram.js, and Karate framework.
Thanks!
Happy API Testing!
Boiler-plate:
Useful links:
Rest-Assured: http://rest-assured.io/
Karate: https://github.com/intuit/karate
Frisby.js: https://docs.frisbyjs.com/
Charam.js: http://dareid.github.io/chakram/