{"id":13732,"library":"pactum","title":"PactumJS REST API Testing Tool","description":"PactumJS is a lightweight and powerful open-source REST API testing tool designed to automate various levels of API testing, including end-to-end (e2e), integration, contract, and component (service level) tests. It emphasizes a clear and comprehensive testing style, utilizing numerous descriptive methods for building requests and defining expectations. The current stable version is 3.9.1, with minor releases occurring frequently, demonstrating active development and maintenance. Key differentiators include its compelling built-in mock server, elegant data management capabilities for dynamic values, robust built-in JSON schema validation, and an extendable architecture. PactumJS supports various JavaScript test runners like Mocha, Jest, and Cucumber, making it adaptable to different testing frameworks and helping simplify complex API testing scenarios across the entire test pyramid.","status":"active","version":"3.9.1","language":"javascript","source_language":"en","source_url":"https://github.com/pactumjs/pactum","tags":["javascript","api","REST","automation","testing","component","service","contract","integration","typescript"],"install":[{"cmd":"npm install pactum","lang":"bash","label":"npm"},{"cmd":"yarn add pactum","lang":"bash","label":"yarn"},{"cmd":"pnpm add pactum","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary function to start a test specification. Use named import for ESM/TypeScript. For CommonJS, use `const { spec } = require('pactum');`.","wrong":"import pactum from 'pactum'; pactum.spec(); // 'spec' is a named export, not a property of a default export","symbol":"spec","correct":"import { spec } from 'pactum'"},{"note":"Import the entire module to access global settings (e.g., `pactum.settings`), `stash`, or other utilities. Use `* as` for ESM or `const pactum = require('pactum');` for CommonJS.","wrong":"import pactum from 'pactum'; // There is no default export; 'pactum' contains named exports and properties","symbol":"pactum (module object)","correct":"import * as pactum from 'pactum'"},{"note":"Type import for the `spec` instance, providing TypeScript users with proper type annotations for their test specifications.","wrong":"import { Spec } from 'pactum'; // 'Spec' is a type, not a runtime value, leading to potential bundler issues or runtime errors if treated as a value","symbol":"Spec","correct":"import type { Spec } from 'pactum'"}],"quickstart":{"code":"import { spec } from 'pactum';\n\ndescribe('HTTPBin API Tests', () => {\n  it('should respond with a 418 status code (teapot)', async () => {\n    await spec()\n      .get('http://httpbin.org/status/418')\n      .expectStatus(418);\n  });\n\n  it('should save a new user via POST request', async () => {\n    // In a real scenario, use process.env.AUTH_TOKEN or a secure method for credentials\n    const authToken = process.env.TEST_AUTH_TOKEN ?? 'Basic aHR0cGJpbjpwYXNzd29yZA==';\n\n    await spec()\n      .post('https://jsonplaceholder.typicode.com/users')\n      .withHeaders('Authorization', authToken)\n      .withJson({\n        name: 'John Doe',\n        email: 'john.doe@example.com',\n        username: 'johndoe'\n      })\n      .expectStatus(201) // POST to /users typically returns 201 Created\n      .expectJsonMatch({ name: 'John Doe', email: 'john.doe@example.com' });\n  });\n});\n","lang":"typescript","description":"Demonstrates basic GET and POST requests, status code assertions, and JSON body matching using PactumJS with an ESM setup and environment variable for authentication."},"warnings":[{"fix":"Install a test runner (e.g., `npm install --save-dev mocha`) and configure your `package.json` scripts to run tests (e.g., `\"test\": \"mocha tests/**/*.js\"`).","message":"PactumJS is a testing library, not a test runner. It must be used in conjunction with a test runner like Mocha, Jest, or Cucumber. Failing to install and configure a test runner will result in no tests being executed.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure all PactumJS operations that return a Promise are prefixed with `await` and that their containing test function is marked `async` (e.g., `it('...', async () => { await spec()... })`).","message":"Asynchronous PactumJS calls (e.g., `spec()`, `spec().toss()`) must be `await`-ed within `async` test functions. Forgetting `await` will cause tests to complete prematurely, potentially leading to false positives or 'timeout' errors in your test runner if it waits for the async operation.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always check the exact casing of the header in the actual API response (e.g., via a proxy or network inspector) or try using a common lowercase variant like `'content-type'`.","message":"When asserting response headers using methods like `expectHeaderContains()` or `expectHeader()`, the header names are often case-sensitive and may require lowercase characters, depending on the server implementation. Forgetting this can lead to 'Header not found' errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Refer to the PactumJS documentation for setting up the `pactumjs-flow-server` (e.g., via Docker) and configuring your project to publish/consume flows and interactions.","message":"Contract testing with PactumJS typically requires the `pactumjs-flow-server` to manage and compare assumed and actual API behaviors. This server needs to be set up and running separately for contract test execution and reporting.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Utilize test runner hooks (`beforeEach`, `afterEach`) to set up and tear down global configurations, or use localized settings within `spec()` chains where possible to ensure test isolation.","message":"Global configurations (e.g., `pactum.settings.setBaseUrl()`, `pactum.settings.setDefaultHeaders()`) can inadvertently affect other tests if not reset or isolated properly. This can lead to test flakiness or unexpected side effects.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'3.9.1':63 'across':127 'activ':70 'adapt':115 'api':3,16,25,124,133 'architectur':101 'autom':21,135 'build':53 'built':80,93 'built-in':79,92 'capabl':87 'clear':43 'compel':78 'complex':123 'compon':36,137 'comprehens':45 'contract':34,139 'cucumb':112 'current':59 'data':85 'defin':56 'demonstr':69 'descript':50 'design':19 'develop':71 'differ':117 'differenti':75 'dynam':89 'e2e':32 'eleg':84 'emphas':41 'end':29,31 'end-to-end':28 'entir':129 'expect':57 'extend':100 'framework':119 'frequent':68 'help':121 'includ':27,76 'integr':33,140 'javascript':105,132 'jest':110 'json':95 'key':74 'level':23,38 'lightweight':9 'like':108 'mainten':73 'make':113 'manag':86 'method':51 'minor':65 'mocha':109 'mock':82 'numer':49 'occur':67 'open':13 'open-sourc':12 'pactumj':1,6,102 'power':11 'pyramid':131 'releas':66 'request':54 'rest':2,15,134 'robust':91 'runner':107 'scenario':126 'schema':96 'server':83 'servic':37,138 'simplifi':122 'sourc':14 'stabl':60 'style':47 'support':103 'test':4,17,26,39,46,106,118,125,130,136 'tool':5,18 'typescript':141 'util':48 'valid':97 'valu':90 'various':22,104 'version':61","created_at":"2026-04-20T01:56:01.908866+00:00","updated_at":"2026-04-20T01:56:01.908866+00:00","problems":[{"fix":"Ensure all PactumJS methods (e.g., `spec()`, `spec().toss()`) are prefixed with `await` and the test function is marked `async`.","cause":"An `async` test function containing PactumJS calls did not `await` all asynchronous operations, causing the test to exit before the HTTP request or assertion completed.","error":"Timeout of 2000ms exceeded. For async tests and hooks, ensure \"done()\" is called or a Promise is returned."},{"fix":"Check the exact casing of the header in the actual API response (e.g., via a proxy or network inspector) or try using a common lowercase variant like `'content-type'`.","cause":"The header name provided in the `expectHeader` or `expectHeaderContains` assertion does not exactly match the case of the header returned by the API.","error":"Error: Header 'Content-Type' not found in response."},{"fix":"Use named import: `import { spec } from 'pactum'` (ESM) or object destructuring: `const { spec } = require('pactum')` (CommonJS).","cause":"Incorrect import statement. `spec` is a named export, not available directly on the `pactum` default import or as a property of a `require`'d module unless explicitly deconstructed.","error":"TypeError: pactum.spec is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.2.0","cli_name":"","cli_version":null,"type":"library","homepage":"https://pactumjs.github.io","github":"https://github.com/pactumjs/pactum","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/pactum","openapi_spec":null,"status_page":null,"smithery":null,"categories":["testing","http-networking"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}