A Complete Guide to PactumJS
Tags: beginners, api, javascript, tutorial
Published: 2023-01-17 15:04:57

## 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"
}
```

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"
  }
}
```

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


```
node_modules
mochawesome-report
```

## 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);
});
```

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(<url>), 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"
  }
}

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


```
npm test

or

npm run test
```

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"
}
```
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');
    });
});
```
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(<url>), 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);
    });
});
```
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');
    });
});
```
### 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');
    });
});
```
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');
    });
});
```
### 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');
    });
});
```
### 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);
    });
});
```
### 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"
  }
}
```
Step 2) Now open the terminal and run the following command:


```
npm test

or

npm run test
```


## 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](https://github.com/codewithmmak/api-testing-pactumjs-mocha-javascript).

If you have any suggestions or found a bug? [Fork this project to help make this even better](https://github.com/codewithmmak/api-testing-pactumjs-mocha-javascript).

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!