TESTEROPS

A pragmatic approach to QA and OPS

SuperTest

With more and more applications now relying on a REST API endpoint , it has become important and necessary to thoroughly test your API endpoints.

Gone are the days when developers and testers could simple do away with manually testing API’s using tools like Postman (which can now be used for automation as well) or Advanced Rest Client. Now a days, knowing how to automate a suite of API’s using some tools like Rest Assured, Chakram is considered to be a vital part of the QA cycle, and a much needed skill for the QA community.

Today, I’m going to give a sample tutorial on one of these API testing tools. SuperTest.

Supertest is library written to test HTTP calls in node.js. So if you want to write test cases which going to do some HTTP calls ( GET, POST, PUT etc ) then this might be the useful tool for you.

We’re going to use Supertest, Mocha, chai for the tests. The API end points can be found on this amazing website https://reqres.in

If you’re not familiar with mocha and chai, I suggest you read first before going in to use these test cases and API automation tool supertest.

Installation

For this purpose I’ve created a sample directory – if you’re using a Mac or Linux, you can use the mkdir directory_name  and then use the cd command to go inside the directory just created.

Inside the directory, use npm init to get started with setting up the project.

Screenshot 2018-10-20 at 7.54.11 PM

Once done , use the npm i or npm install command to install supertest, mocha, chai and mochawesome, which we will use for reporting purposes.

Screenshot 2018-10-20 at 7.58.40 PM

Now inside the root of the directory, create a new folder called test. Here we’re going to keep all the .js files that we’re going to use for tests.

GET REQUEST

Head over to https://reqres.in to get a sample GET endpoint for use. We’ll be using the following endpoint

https://reqres.in/api/users?page=2

which outputs a sample response of this type

{
    "page": 2,
    "per_page": 3,
    "total": 12,
    "total_pages": 4,
    "data": [
        {
            "id": 4,
            "first_name": "Eve",
            "last_name": "Holt",
            "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
        },
        {
            "id": 5,
            "first_name": "Charles",
            "last_name": "Morris",
            "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
        },
        {
            "id": 6,
            "first_name": "Tracey",
            "last_name": "Ramos",
            "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
        }
    ]
}

Now copy paste this code in a new file – let it be list_users.js


const supertest = require('supertest');
const expect = require('chai').expect;
const schema = require('../validation/list_users_schema');
const joi = require('joi');
let baseURL = supertest("https://reqres.in");
let list_users = "/api/users?page=2";
describe('First Request to Get Users',()=>{
let res;
it("See Response", async function () {
res = await baseURL.get(list_users); //Sending the GET request
console.log(res.body);
});
it('checks that the response was OK',async()=>{
await (expect(res.status).to.equal(200));
});
it('asserts the various attributes',async ()=>{
await(expect(res.body.page).to.equal(2));
});
it('checks that the data is an array',async ()=>{
await (expect(res.body.data).to.be.an('array'));
});
it('prints length of data array',async()=>{
await (console.log(res.body.data.length));
});
it('gets the id from the array',async()=>{
for(let i=0;i<res.body.data.length;i++){
await(console.log(res.body.data[i].id));
await (console.log(res.body.data[i].first_name));
}
});
it('matches the schema for the API',async()=>{
await (expect(joi.validate(schema.schema).error).to.be.null);
})
});

view raw

list_users.js

hosted with ❤ by GitHub

Now, let’s dwell in this code and see what is happening. As you can see from the first few lines, we’re using the get verb.

 

Now before running this test, head over to you package.json file and add this in the test command , under the scripts flag

"test" : "mocha test --reporter mochawesome"

Your package.json file should look like this

Screenshot 2018-10-20 at 10.45.19 PM

 

Now run this test from command prompt or use Ctrl + ~  to open the command prompt in Visual Studio Code itself – and do

npm test

and see the output

Screenshot 2018-10-20 at 7.20.15 PM

We’re using a couple of simple assertions like the status code is 200, and checking values of a couple of attributes like page value to equal 2.

Another assertion is that the data key inside the main response body is an array. And a couple of other assertions that length of array is something.

The last assertion is something different. Let’s talk about it in detail.

tl:dr; this assertion is validating that the API response matches a given schema for the API. In order to do that we have used the joi package from npm.

Start by installing joi from the npm repository using

npm i joi

Now we create a new directory inside the root directory of the folder that we’ve created for our tests. Let’s call it validation. Inside this folder, create a new file called list_users_schema.js where we’re going to put the schema file for the GET request API.

Now, let’s look at the schema of the API.

We have an JSON object, which contains a number of entries, like page, per_page, and an array of objects data, which we asserted above to be an array.

To define the schema, let’s have this code pasted.


const joi = require('joi');
module.exports = {
schema : joi.object().keys({
page : joi.number().integer().required(),
per_page: joi.number().integer().required(),
total : joi.number().integer().required(),
total_pages: joi.number().integer().required(),
data : joi.array().items(joi.object({
id: joi.number().integer().required(),
first_name : joi.string().required(),
last_name : joi.string().required(),
avatar : joi.string().uri().required()
}))
})
}

Here, we’re defining the corresponding enteries and their types – we can add a whole range of checks for the API schema. Head over to the github link of joi to learn more and how we can add schema checks for JSON objects or JSON arrays.

Once we have the schema, we call it in the list_users.js file at the top and then apply the assertion that there is no error when checking the schema.

 

POST REQUEST

Head over to https://reqres.in to get a sample POST endpoint for use. We’ll be using the following endpoint

https://reqres.in/api/users

Let’s create a new file called create_user.js inside the test folder and copy paste this code


const supertest = require('supertest');
const expect = require('chai').expect;
const schema = require('../validation/list_users_schema');
const joi = require('joi');
let baseURL = supertest("https://reqres.in&quot;);
let list_users = "/api/users";
describe('POST Request',()=>{
let post_resp;
it('makes a POST call ',async ()=>{
post_resp = await baseURL.post(list_users)
.type('form')
.send({
"name": "morpheus",
"job": "leader"
})
.set('Accept','/application/\json/');
await (console.log(post_resp.body));
});
it('asserts that the response code is 201',async ()=>{
await (expect(post_resp.status).to.eql(201));
})
});

view raw

create_user.js

hosted with ❤ by GitHub

 

PS : In order to send a POST call, for some reason, you need to add the type('form') in the POST call as evident from the syntax. I couldn’t find a reason for the same but this has been mentioned here.

Once done, save the file, head over to the terminal and again run the test using npm test. If you only want this test to run , add a .only in front of the it block in the test  like it.only('something') and it will only run that test. The output comes like this

Screenshot 2018-10-20 at 7.20.02 PM

 

Let’s add an assertion that the status returned is 201 - Created


const supertest = require('supertest');
const expect = require('chai').expect;
const schema = require('../validation/list_users_schema');
const joi = require('joi');
let baseURL = supertest("https://reqres.in&quot;);
let list_users = "/api/users";
describe('POST Request',()=>{
let post_resp;
it('makes a POST call ',async ()=>{
post_resp = await baseURL.post(list_users)
.type('form')
.send({
"name": "morpheus",
"job": "leader"
})
.set('Accept','/application/\json/');
await (console.log(post_resp.body));
});
it('asserts that the response code is 201',async ()=>{
await (expect(post_resp.status).to.eql(201));
})
});

view raw

create_user.js

hosted with ❤ by GitHub

 

We can see that the assertion passes

Screenshot 2018-10-20 at 10.56.58 PM

 

Now, as you see we have both the GET and POST request automated with supertest. You can now add any assertion that you want in the tests- be it about the size , type of output, status code etc.

All these tests have been combined in a nice github repository – https://github.com/zac11/supertest-demo

Clone this repository and cd to go inside it and do npm install to install the dependencies. Once done , do npm test to run the test files

Screenshot 2018-10-20 at 11.00.45 PM

 

Go inside the root directory and locate a folder named mochawesome-report and inside you’ll see the html report. Open the report in any browser and you’ll see something like this –

Screenshot 2018-10-20 at 11.02.54 PM

 

Apart from GET and POST, the repository also contains a DELETE verb and PUT verb call to demonstrate how it can be done.

 

Please share and follow my blog for more such automation content.

 

One thought on “SuperTest

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: