API Automation With Pactum.JS

Hello everyone! 👋

In the ever-evolving landscape of software development, the significance of robust API automation cannot be overstated. Recently, my focus has been on enhancing API test coverage and refining an automation framework. The goal? To make future automation endeavors in the same category more efficient and less time-consuming than the initial tool adoption.

Through this blog, I aim to share insights into Pactum.js, shedding light on its capabilities, my hands-on experience, and the advantages and challenges it brings to the table. This is not just a blog; it's a knowledge-sharing platform. I invite you all to explore the world of API automation with Pactum.js and, as you do, let me know if there are better, faster, or more efficient ways to achieve the same goals. Your feedback is invaluable! 🙂
Let’s dive into the realm of Pactum.js — a free and open-source REST API automation library — and uncover the potential it holds for elevating your API testing game 💪

PactumJs

As the definition goes, PactumJS is a free & open-source REST API Automation library for all levels in a Test Pyramid written in JavaScript.It serves as a comprehensive toolkit, offering essential components to enhance the creation of effective and efficient API automation tests.

Its a library that provides the necessary ingredients for the most common things to write better API automation tests.

Getting Started

So, My requirements was to do testing of the API’s as our product is driven through api’s and the api’s are developed to be used by other teams directly or with our frontend SDK.
We moved with PactumJs library with Jest Test Runner

What is Jest ?

Jest is a JavaScript testing framework that is widely used for testing JavaScript code, including applications, libraries, and frameworks

Step 1: Install Node.js & ensure it is working.

Step 2: Create a Folder for tests (i prefer this way)

Step 3: Install pactum & jest (test runner).

npm install pactum jest

Step 4: Running Tests

  "main": "jest.config.js",
  "scripts": {
    "test": "./node_modules/.bin/jest",
  },

Here the “jest.config.js” has the test config maxWorkers, Reporters, testEnvironment, etc.. (Configuration Options)

jest.config.js (sample example)

/** @type {import('jest').Config} */

module.exports = {
  // Display name configuration for the test suite
  displayName: {
    name: "TESTS",
    color: "blue",
  },
  // Set a maximum timeout for each test
  testTimeout: 180000,
  // Set the maximum number of concurrent test suites
  maxConcurrency: 3,
  // Set the maximum number of worker processes for running tests
  maxWorkers: 2,
  // Set the verbosity of the test output
  verbose: false,
  // Specify the reporters for test output
  reporters: [
    "default",
  ],
};

with the above setup you should be ready to run the test

npm run test // Run all test using command
npm run test <file_name> // Run all test using command (when individual file testing)
npm run test -- -t @<tag> // Run specific tags in test files

Writing Your First Pactum Test

Test File : example.js

// Test File
const { spec } = require('pactum');

describe(`Integration Services API Test Cases Around Common API's PM-TOOL ${tool}, @regression @${tool}`, function () {
    request.setBaseUrl(`${constants.API_HOST}/v1`);
    request.setDefaultTimeout(6000); 

    it.concurrent("Fetch user details from generated User Access Token JIRA integration service using uat generated from username and accesskey", async () => {
      await commonHelper.makeAPIRequest("get", "/users", accessToken, queryParams, expectedStatusCode, expectedResponse);
      // or
      const request = await spec()
        .get(`${endpoint}`)
        .withHeaders("Authorization", `Bearer ${accessToken}`)
        .withQueryParams(queryParams)
        .expectStatus(statusCode)
        .expectJsonMatchStrict(expectedJson)
    });

    // other test cases
});

commonHelper file:

async makeAPIRequest(method = 'get', endpoint, accessToken, queryParams, statusCode, expectedJson, requestBody) {
      const request = spec()[method](`${endpoint}`)
        .withHeaders("Authorization", `Bearer ${accessToken}`)
        .withQueryParams(queryParams);
      if (requestBody) {
        request.withJson(requestBody);
      }
      request.expectStatus(statusCode)
      if (expectedJson) {
        request.expectJsonMatchStrict(expectedJson);
      }
      return request;
  },
  • withHeaders() — to pass headers

  • withQueryParams() — to pass query params

  • withAuth() — to pass basic auth details

  • withJson() — to pass request body in the request

  • expectedStatus() — to assert with expected Status

  • expectJsonMatchStrict() — to assert with expected Json/response

Please find more from the link

Advantages of Pactum:

  1. Easy to Write Syntax

  2. Chainable API

  3. Request Configuration

  4. Response Validation

  5. Dynamic Data Handling

  6. Data-Driven Testing

  7. Request and Response Logging

  8. Test Hooks

  9. Mocking and Stubbing

Few Best Practices I would suggest:

  1. Group Test Cases in Different Files respective to their common functionality.

  2. Clear and Descriptive Test Naming

  3. Have Assertions for each test case atleas basic assertion

  4. Parameterization and Data-Driven Tests

  5. Run Tests in Isolation

  6. Monitor Test Execution Time

  7. Regularly Review and Refactor Tests

Few Challenges with PactumJs :

  1. Storing Request/Response for custom purpose

  2. Limited Reporting

  3. Scalability & Flexibility

  4. Limited Ecosystem Support

  5. Low Community Size

It’s important to note that the suitability of Pactum depends on the specific needs and constraints of your project.

Conclusion:

Managing and executing around 300 test cases, I've witnessed a remarkable coverage of 97%, coupled with a stability rate of 98–99% on the initial run—truly a testament to its efficacy😄

While my experience with Pactum has been overwhelmingly positive, it’s essential to acknowledge the challenges it poses, particularly in the realms of Limited Reporting and Flexibility as i wanted to store the request response but there is no direct way i can do it , there are ways but those are not best practice and are kind of hacks which will require a whole revamp of my whole testing architecture.

In summary, this blog has unveiled the power of Pactum in API automation. Empower yourself to explore the depths of API testing with Pactum, and consider the provided resources for continued learning.

Additional Resources

Thank you for joining me on this exploration of API automation. May your testing endeavors be efficient, insightful, and, most importantly, successful. Happy testing! 😊