PactumJS Documentation

repository·master·Indexed 20 days ago

https://github.com/pactumjs/pactum

A lightweight REST API testing tool for all levels of the test pyramid, including E2E, integration, contract, and component testing. PactumJS features a spec() builder pattern for constructing HTTP requests and expectations, a built-in mock server for simulating HTTP/HTTPS-based APIs, and support for integration with test runners like Mocha, Jest, and Cucumber. It allows for extensibility through custom handlers for the request lifecycle, custom reporters, and configurable mock interactions.

Tokens
10.6K
Snippets
47
Records
61
Agent score
65%

What's inside PactumJS

  1. Install PactumJS

    master

    To use PactumJS, install it as a development dependency. You should also install a test runner like Mocha, Jest, or Cucumber to execute your tests.

    Alternatively, you can use the npx pactum-init command to scaffold a new project automatically.

    # install pactum as a dev dependency
    npm install --save-dev pactum
    
    # install a test runner to run pactum tests
    npm install --save-dev mocha

    or use the initializer

    npx pactum-init

  2. Perform API Testing with spec()

    master

    PactumJS uses a spec() builder pattern to construct HTTP requests and define expectations. You can chain methods like .get(), .post(), .withHeaders(), and .withJson() to build the request, and use .expectStatus() or other expectation methods to validate the response.

    To execute the test in a Mocha environment, use the mocha command pointing to your test file.

    const { spec } = require('pactum');
    
    it('should be a teapot', async () => {
      await spec()
        .get('http://httpbin.org/status/418')
        .expectStatus(418);
    });
    
    it('should save a new user', async () => {
      await spec()
        .post('https://jsonplaceholder.typicode.com/users')
        .withHeaders('Authorization', 'Basic xxxx')
        .withJson({
          name: 'bolt',
          email: 'bolt@swift.run'
        })
        .expectStatus(200);
    });
  3. Define an Interaction for the Mock Server

    master

    An Interaction object defines how the mock server should respond to specific incoming requests. It consists of a request and a response.

    Request Configuration (InteractionRequest)

    Required fields:

    • method: The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'TRACE').
    • path: The endpoint path.

    Optional fields:

    • headers: Object containing request headers.
    • body: The request body.
    • pathParams: Object for path parameters.
    • queryParams: Object for query parameters.
    • cookies: Object for cookies.
    • form: Object for form data.
    • graphQL: An object containing a query (string) and optional variables (object).

    Response Configuration (InteractionResponse)

    A response can be a simple static response or a conditional response using onCall.

    Static Response: Requires a status (number) and can include:

    • headers: Object of response headers.
    • cookies: Object of response cookies.
    • body: The response body.
    • file: Path to a file to be returned as the body.
    • fixedDelay: A number representing a delay in milliseconds.
    • randomDelay: An object with { min: number, max: number } for a randomized delay.
    • onCall: An object used for stateful/sequential responses.

    Conditional Response (onCall): If onCall is provided, the response can change based on the call count. The onCall object uses the call number as a key to define subsequent responses.

    Interaction Metadata

    • id: Unique identifier for the interaction.
    • provider: Name of the provider.
    • flow: The flow of the provider.
    • strict: Boolean to enforce strict matching.
    • expects: InteractionExpectations to verify if an interaction was exercised or check its callCount.
    const interaction: Interaction = {
      request: {
        method: 'POST',
        path: '/login',
        body: { username: 'admin' }
      },
      response: {
        status: 200,
        body: { token: 'secret-token' },
        onCall: {
          1: { status: 200, body: { token: 'first-token' } },
          2: { status: 401, body: { error: 'Too many attempts' } }
        }
      }
    };
  4. Integrate PactumJS with Cucumber

    master

    You can use PactumJS within Cucumber step definitions. A common pattern is to initialize a spec object in a Before hook, use the spec methods within Given and When steps, and use await spec.toss() to execute the request. Assertions can be performed on the response object in the Then step.

    For a complete setup, refer to the pactum-cucumber-boilerplate repository.

    Scenario: Check Tea Pot
      Given I make a GET request to "http://httpbin.org/status/418"
      When I receive a response
      Then response should have a status 418
    // steps.js
    const pactum = require('pactum');
    const { Given, When, Then, Before } = require('@cucumber/cucumber');
    
    let spec = pactum.spec();
    
    Before(() => { spec = pactum.spec(); });
    
    Given('I make a GET request to {string}', function (url) {
      spec.get(url);
    });
    
    When('I receive a response', async function () {
      await spec.toss();
    });
    
    Then('response should have a status {int}', async function (code) {
      spec.response().should.have.status(code);
    });
  5. Use PactumJS as a Mock Server

    master

    PactumJS can act as a standalone mock server to simulate HTTP/HTTPS-based APIs. You define interactions using mock.addInteraction(), specifying the request (method and path) and the desired response (status and body). Finally, call mock.start(port) to begin listening for requests on the specified port.

    const { mock } = require('pactum');
    
    mock.addInteraction({
      request: {
        method: 'GET',
        path: '/api/projects'
      },
      response: {
        status: 200,
        body: [
          {
            id: 'project-id',
            name: 'project-name'
          }
        ]
      }
    });
    
    mock.start(3000);
  6. Configure PactumJS logging via environment variables

    master

    You can control the logging behavior of PactumJS using environment variables. This is useful for CI/CD environments or when you want to change log verbosity without modifying code.

    • PACTUM_LOG_LEVEL: Sets the minimum log level. Supported values are TRACE, DEBUG, INFO, WARN, ERROR, SILENT, and VERBOSE.
    • PACTUM_DISABLE_LOG_COLORS: Set to true to disable colored output in the logs.
  7. Use a custom logger with setLogger

    master

    If you want to redirect PactumJS logs to your own logging framework (like Winston or Bunyan), you can provide a custom Logger object via setLogger. The object must implement the following methods, each accepting an array of messages:

    • trace(messages: any[])
    • debug(messages: any[])
    • info(messages: any[])
    • warn(messages: any[])
    • error(messages: any[])
    import { setLogger } from 'pactum';
    
    setLogger({
      trace: (msgs) => console.log('[TRACE]', ...msgs),
      debug: (msgs) => console.log('[DEBUG]', ...msgs),
      info: (msgs) => console.log('[INFO]', ...msgs),
      warn: (msgs) => console.warn('[WARN]', ...msgs),
      error: (msgs) => console.error('[ERROR]', ...msgs),
    });
  8. Manage data templates with stash

    master

    Data templates allow you to define structured data patterns. Use stash.addDataTemplate to add templates as objects, arrays, or single key-value pairs. Retrieve templates using stash.getDataTemplate(path).

    // Adding templates via object
    stash.addDataTemplate({
      'User:NewUser': {
        'Name': 'Snow',
        'Age': 26,
        'Address': []
      }
    });
    
    // Adding templates via key-value pair
    stash.addDataTemplate('USER:NEW', { name: 'john', age: 28 });
    
    // Retrieving a template
    const credentials = stash.getDataTemplate('CREDENTIALS');
  9. Use Logger methods for manual logging

    master

    The Logger plugin exposes several methods to emit logs at different severity levels. Logs are only emitted if the current log level is equal to or higher than the method's severity.

    Available methods:

    • trace(...msg)
    • debug(...msg)
    • info(...msg)
    • warn(...msg)
    • error(...msg)
  10. Create a request flow with flow()

    master

    Use flow(name: string) to return an instance of a Spec associated with a specific named flow. This is used to manage sequences of requests.

    import { flow } from 'pactum';
    
    const myFlow = flow('login-and-get-profile');
  11. Configure PactumJS log levels

    master

    You can control the verbosity of PactumJS logs using setLogLevel. This is useful for reducing noise in CI environments or increasing detail during debugging.

    Supported log levels are:

    • 'VERBOSE'
    • 'TRACE'
    • 'DEBUG'
    • 'INFO'
    • 'WARN'
    • 'ERROR'
    • 'SILENT'
    import { setLogLevel } from 'pactum';
    
    setLogLevel('DEBUG');
  12. Retrieve internal keys for maps, templates, and functions

    master

    Use these methods to retrieve the underlying keys used by the stash system:

    • stash.getMapKey(key: string): string
    • stash.getDataTemplate(path: string): object (Note: The interface also provides getFunctionKey(key: string): string)
    • stash.getStoreKey(key: string): string