DEV Community

Cover image for A Complete Guide to PactumJS
Md Moeen Ajaz Khan
Md Moeen Ajaz Khan

Posted on • Originally published at programsbuzz.com

A Complete Guide to PactumJS

Introduction

If you are looking for a JavaScript-based API automation tool that can help in API testing at all the levels in a Test Pyramid then your search will end here, it’s PactumJS an open-source library. Testing backends is made faster and more enjoyable with it. All the necessary ingredients are provided in this library to write better API automation tests easily, and quickly.

PactumJS is a REST API Testing Tool used to automate e2e, integration, contract & component (or service level) tests.

There are many HTTP client, HTTP server, and validation packages available in the Node.js ecosystem, but PactumJS is designed specifically for testing. It is inspired by a frisby and pact. The original versions of this library were compatible with them, but later became a separate test tool.

Getting Started

Step 1) To start with you need to have Node.js installed on your machine. You can download it directly from the Node.js website and install it on your machine if you are not already using it.

Once installed check the version:

node -v

Step 2) Download and Install Visual Studio Code (this will help you write formatted code but you can pick any text editor of your choice)

Step 3) Open Visual Studio Code

Step 4) Open your integrated Terminal and run the following command

mkdir api-testing-pactumjs-mocha-javascript

Step 5) Open the directory

cd api-testing-pactumjs-mocha-javascript

Step 6) Create a new package.json file with default values

npm init -y

Your package.json file should be like this:

{
  "name": "api-testing-pactumjs-mocha-javascript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
Enter fullscreen mode Exit fullscreen mode

Step 7) I will be using Mocha JavaScript test framework for writing the API tests, mochawesome to generate HTML reports and FakerJS, one of the powerful packages to generate dummy data. Install all the required packages

npm install --save-dev pactum mocha @faker-js/faker

Once the installation is complete node_module will be created with all the dependencies installed in it.

Your package.json file should look like this:

{
  "name": "api-testing-pactumjs-mocha-javascript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@faker-js/faker": "^7.6.0",
    "mocha": "^10.2.0",
    "pactum": "^3.3.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 8) Create a .gitignore file so that unwanted files are not committed to the repository

node_modules
mochawesome-report
Enter fullscreen mode Exit fullscreen mode

Writing Tests

Step 1) Create a folder test-api.

Step 2) Under this folder create a file getUserTest.js.

Step 3) Now we can start writing API tests.

const { spec } = require('pactum');

it('should get a response with status code 200', async () => {
    await spec()
        .get('https://reqres.in/api/users/2')
        .expectStatus(200);
});
Enter fullscreen mode Exit fullscreen mode

Line #1: Import - we are importing the PactumJS library

Line #3: ‘it’ - it’s an individual test case (Read more about the MochaJS library here: Mocha - the fun, simple, flexible JavaScript test framework )

Line #4: spec provides an object to performance request with parameters, headers, cookies, body, files etc. It provides the ability to chain methods.

Line #5: In the example, we are fetching user details by using .get(), it makes an HTTP GET request on the provided endpoint and gives us back the response.

Line #6: expect - is to validate the response code (i.e. 200) after the request is made.

Running Tests

Step 1) Update the test scripts in package.json file

{
  "scripts": {
    "test": "mocha ./test-api/*.js"
  }
}

Enter fullscreen mode Exit fullscreen mode

Step 2) Now open the terminal and run the following command:

npm test

or

npm run test
Enter fullscreen mode Exit fullscreen mode

If a test fails, then this library will print the complete request, response, and gives you the AssertionError in the terminal. This will help you in further debugging the code

E2E API Testing Test Strategy

In this article we will be using Reqres - A hosted REST-API ready to respond to your AJAX requests to write end-to-end API tests. Its a hosted REST API and we will be able to verify the responses in real-time, no need of providing any sample data. For easy understanding I have created simple e2e API testing strategy and I have followed the steps given below:

POST - Create a user by providing data from the JSON file. Also as the real-time approach, I have used the Fakerjs npm package which will give you test data.

Response Validation - Assert the response by either comparing it with JSON data or by matching it with data stored in the variable.

GET - Get the user details by using some of the technique of query param, without query param and path param. And finally assert the response for each.

PUT - Update user attributes for an existing resource and assert the response.

PATCH - Partially update an existing resource (not all attributes required) and assert the response.

DELETE - Finally we will delete the user and assert the response code.

Base Setup

We will store the environment details separately and use dotenv npm package to store base URI. Lets install the dependency and save it:

npm install dotenv --save-dev

Create a .env file in root folder and add below line:

PACTUM_REQUEST_BASE_URL=https://reqres.in
We will generate the test result in html by using mochawesome to better analyze the test results:

npm install mochawesome --save-dev
POST Request using test data from JSON file
We are going to send a POST request by providing test data from json file. Create a folder at root level named test-data and then create a JSON file named user-data.json.

Since the POST request endpoint https://reqres.in/api/users will accept name and job, we will provide same in JSON.

{
    "name": "Mike Tyson",
    "job": "Boxer"
}
Enter fullscreen mode Exit fullscreen mode

Under test-api folder create a test file named postJsonTest.js. Now, lets write the post request:

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;
const userData = require('../test-data/user-data.json');

describe('POST API tests using PactumJS', () => {

    it('should successfully pass the test for post API when test data from JSON file is used', async () => {
        await spec()
            .post(baseUrl + '/api/users')
            .withJson(userData)
            .expectStatus(201)
            .expectJsonMatch('name', 'Mike Tyson')
            .expectJsonMatch('job', 'Boxer');
    });
});
Enter fullscreen mode Exit fullscreen mode

Line #1: Import - we are importing the PactumJS library

Line #2 & 3: We have specified our URI in config file, we need to require it.

Line #4: We need JSON test date so we need to require it.

Line #6: ‘describe’ function is used to group tests. It accepts a string to describe the group of tests and a callback function which contains it() tests.

Line #8: ‘it’ - it’s an individual test case. Note that one describe block can contain multiple it blocks, which means multiple tests.

Line #9: spec provides an object to performance request with parameters, headers, cookies, body, files etc. It provides the ability to chain methods.

Line #10: In the example, we are fetching user details by using .get(), it makes an HTTP GET request on the provided endpoint and gives us back the response.

Line #12: expect - is to validate the response code (i.e. 200) after the request is made.

POST Request by using FakerJS package to generate test data

Under test-api folder create a test file named postFakerJsTest.js. We are going to send a post request by calling test data generated by fakerjs.

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;
const { faker } = require('@faker-js/faker');

const randomName = faker.name.firstName();
const randomJob = faker.name.jobTitle();

describe('POST API tests using PactumJS', () => {

    it('should successfully pass the test for post API when test data generated using fakerjs', async () => {
        await spec()
            .post(baseUrl + '/api/users')
            .withJson({
                "name": randomName,
                "job": randomJob
            })
            .expectStatus(201)
            .expectJsonMatch('name', randomName)
            .expectJsonMatch('job', randomJob);
    });
});
Enter fullscreen mode Exit fullscreen mode

Line #4: Import - we are importing the FakerJS library

Line #6 & 7: We are generating firstName and jobTitle using FakerJS and storing them into a const.

Line #14: withJson we are passing the const name and job.

Line #19 & 20: We are verifying name and job in response with const generated by FakerJS library.

GET Request

Under test-api folder create a test file named getSingleUserTest.js. We are going to send a GET request:

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;

describe('GET API tests using PactumJS', () => {

    it('should successfully pass the test for single user GET API', async () => {
        await spec()
            .get(baseUrl + '/api/users/2')
            .expectStatus(200)
            .expectJsonMatch('data.id', 2)
            .expectJsonMatch('data.first_name', 'Janet');
    });
});
Enter fullscreen mode Exit fullscreen mode

GET Request using query param

Under test-api folder create a test file named getSingleUserQueryParamTest.js.

We are going to send a GET request with query parameters:

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;

describe('GET API tests using PactumJS', () => {

    it('should successfully pass the test for single user GET API using query param', async () => {
        await spec()
            .get(baseUrl + '/api/users')
            .withQueryParams({ page: '2' })
            .expectStatus(200)
            .expectJsonMatch('page', 2)
            .expectJsonMatch('data[0].id', 7)
            .expectJsonMatch('data[0].first_name', 'Michael');
    });
});
Enter fullscreen mode Exit fullscreen mode

In the above example we are passing query params and it used as withQueryParam(key, value). This will help us to pass query params with the request.

PUT Request

Create a file named putTest.js and write the following code:

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;
const updatedUserData = require('../test-data/updated-user-data.json');

describe('PUT API tests using PactumJS', () => {

    it('should successfully pass the test for PUT API', async () => {
        await spec()
            .put(baseUrl + '/api/users/2')
            .withJson(updatedUserData)
            .expectStatus(200)
            .expectJsonMatch('name', 'Floyd Joy Mayweather Jr.')
            .expectJsonMatch('job', 'Boxer Two');
    });
});
Enter fullscreen mode Exit fullscreen mode

PATCH Request

Create a file named patchTest.js and write the following code:

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;
const minorUpdatedUserData = require('../test-data/minor-updated-user-data.json');

describe('PATCH API tests using PactumJS', () => {

    it('should successfully pass the test for PATCH API', async () => {
        await spec()
            .put(baseUrl + '/api/users/2')
            .withJson(minorUpdatedUserData)
            .expectStatus(200)
            .expectJsonMatch('job', 'Boxer');
    });
});
Enter fullscreen mode Exit fullscreen mode

DELETE Request

Create a file named deleteTest.js and write the following code:

const { spec } = require('pactum');
require('dotenv').config()
const baseUrl = process.env.PACTUM_REQUEST_BASE_URL;

describe('DELETE API tests using PactumJS', () => {

    it('should successfully pass the test for DELETE API', async () => {
        await spec()
            .delete(baseUrl + '/api/users/2')
            .expectStatus(204);
    });
});
Enter fullscreen mode Exit fullscreen mode

Test Report

We are going use mochawesome package to generate html report and it will be placed under root directory with name mochawesome-report

Step 1) Update the test scripts in package.json file

{
  "scripts": {
    "test": "mocha ./test-api/*.js --reporter spec --reporter mochawesome --timeout 5000"
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 2) Now open the terminal and run the following command:

npm test

or

npm run test
Enter fullscreen mode Exit fullscreen mode

Conclusion

While writing this article I have tried to use all the basic operations done from scratch to set up an API automation framework, project initiation, set common components, explained requests: POST, GET, PUT, PATCH and DELETE requests, and finally how we can generate mochawesome report (Checkout my example code to generate Allure report).

However, there are several advanced features which can be found in PactumJS Guide, that you may want to try.

Code Repository

All the code written above can be found on GitHub.

If you have any suggestions or found a bug? Fork this project to help make this even better.

Star the repo and follow me to get the latest updates

What Do You Think?

Did this work for you?

Could I have done something better?

Have I missed something?

Please share your thoughts and let me know if there are particular things that you would enjoy reading further.

Cheers!

Top comments (0)