Write gRPC scripts and tests in Postman using the pm object

Postman provides JavaScript APIs with the pm object, enabling you to test and access request and response data in your gRPC scripts run in the Postman Sandbox. This guide covers how to use the pm object for accessing request details, handling responses, writing assertions, using variables, and sending HTTP requests in the Postman Sandbox.

The pm object

The pm object provides functionality for testing your request and response data, access to variables, and some meta information.

Accessing contextual information in scripts

pm.request

The pm.request object provides access to the request data inside your scripts. pm.request is available in both Before invoke and After response scripts.

The following are the properties of the pm.request object:

  • The request URL:

    pm.request.url: Url

  • The package, service, and method name in the format packageName.serviceName.methodName:

    pm.request.methodPath: string

  • Authentication details:

    pm.request.auth: Auth

  • The list of metadata sent with the request:

    pm.request.metadata: PropertyList<{ key: string, value: string }>

    An individual metadata item is an object with the properties key and value.

  • The list of outgoing messages:

    pm.request.messages: PropertyList<{ data: any, timestamp: Date }>

    An individual message is an object with the following properties:

    • data - The sent message content
    • timestamp - The time the message was sent, represented as a Date object

    For requests with unary and server streaming methods, pm.request.messages will contain only one message at index 0 which can be accessed as pm.request.messages.idx(0).

Note: Request mutation isn't supported in the pm object.

pm.message

The pm.message object provides access to the data returned in the message that's received from the server. pm.message is only available in On message scripts.

The following are the properties of the pm.message object:

  • The incoming message:

    pm.message: PropertyList<{ data: any, timestamp: Date }>

    An individual message is an object with the following properties:

    • data - The received message content
    • timestamp - The time the message was received, represented as a Date object

pm.response

The pm.response object provides access to the data returned in the response for the current request execution. pm.response is only available in After response scripts.

The following are the properties of the pm.response object:

  • The gRPC response status code:

    pm.response.statusCode: number

  • Response time (in milliseconds):

    pm.response.responseTime: number

    For requests with streaming methods, responseTime denotes the total duration for that request execution.

  • The list of metadata received with the response:

    pm.response.metadata: PropertyList<{ key: string, value: string }>

    An individual metadata item is an object with the properties key and value.

  • The list of trailers received with the response:

    pm.response.trailers: PropertyList<{ key: string, value: string }>

    An individual trailer item is an object with the properties key and value.

  • The list of incoming messages:

    pm.response.messages: PropertyList<{ data: any, timestamp: Date }>

    An individual message is an object with the following properties:

    • data - The received message content
    • timestamp - The time the message was received (Date)

    For requests with unary and client streaming methods, pm.response.messages will contain only one message at index 0 which can be accessed as pm.response.messages.idx(0).

pm.info

The pm.info object provides meta information related to the request and the script itself, including the request name, request ID, and name of the execution hook.

The following are the properties of the pm.info object:

  • The name of execution hook. It will be either beforeInvoke, onIncomingMessage, or afterResponse depending if the script is executing in Before invoke, On message, or After response hook, respectively.

    pm.info.eventName: 'beforeInvoke' |'onIncomingMessage' | 'afterResponse'

  • A unique ID that identifies the current request inside which the script is running:

    pm.info.requestId: string

  • The request name:

    pm.info.requestName: string

Writing assertions

You can add test specifications and assertions to your scripts using the pm.test and pm.expect functions respectively.

pm.test

  • Use the pm.test function to add test specifications to your Before invoke, On message, or After response script.

    pm.test: (testName: string, specFunction: Function) => pm

    Use testName to help you identify the test in the Test results section and also communicate the test's purpose to the consumers of your collection.

    specFunction is where you define the assertions on request and response data using the pm.expect function.

    The pm.test method returns the pm object, making the call chainable.

    Example test suite:

    pm.test("response should have 'content-type' metadata", function () {
      pm.response.to.have.metadata('content-type', 'application/grpc');
    });
    

    An optional done callback can be passed to pm.test, to test asynchronous functions:

    pm.test('async test', function (done) {
      setTimeout(() => {
        pm.expect(pm.response.statusCode).to.equal(0);
        done();
      }, 1500);
    });
    

    You can also include multiple assertions to group the related ones in a single test:

    pm.test("Should receive update events for both users", function () {
      pm.response.messages.to.include({ action: 'update', userId: 'user1' });
      pm.response.messages.to.include({ action: 'update', userId: 'user2' });
    });
    
  • Get the total number of tests run from a specific location in code:

    pm.test.index: () => number

  • Skip a test using:

    pm.test.skip: (testName: string, specFunction: Function) => pm

pm.expect

The pm.expect method enables you to write assertions on your request and response data, using ChaiJS expect BDD syntax.

pm.expect: (assertOn: any) => Assertion

You can also use pm.request.to.have.*, pm.response.to.have.* and pm.response.to.be.* to build your assertions.

pm.response.to.have.statusCode(0);
pm.expect(pm.response.responseTime).to.be.below(200);

Check out the examples section for more assertions.

Using variables in scripts

Head over to the Postman JavaScript reference to learn about using variables in scripts.

Sending HTTP request from scripts

You can use the pm.sendRequest method to send HTTP requests asynchronously from Before invoke, On message, and After response scripts.

pm.sendRequest: (request: string | RequestDefinition, callback?: (error: any, response: Response)) => void

You can pass the pm.sendRequest method a URL string, or a complete request definition object including headers, method, body, and more.

// Example with a plain string URL
pm.sendRequest('https://postman-echo.com/get', (error, response) => {
  if (error) {
    console.error(error);
  } else {
    console.log(response.json());
  }
});
// Example with a full-fledged request
const request = {
  url: 'https://postman-echo.com/post',
  method: 'POST',
  header: {
    'Content-Type': 'application/json',
    'X-Foo': 'bar'
  },
  body: {
    mode: 'raw',
    raw: JSON.stringify({ key: 'this is json' })
  }
};

pm.sendRequest(request, (error, response) => {
  console.log(error ? error : response.json());
});
// Example containing a test
pm.sendRequest('https://postman-echo.com/get', (error, response) => {
  if (error) {
    console.log(error);
  }

  pm.test('Response is OK', () => {
    pm.expect(error).to.equal(null);
    pm.expect(response).to.have.property('code', 200);
    pm.expect(response).to.have.property('status', 'OK');
  });
});

Import packages from scripts

You can use the pm.require method to import packages from your team's Package Library or external package registries inside Before invoke, On message, and After response scripts in your requests.

The pm.require method accepts the name of the package. Declare the method as a variable if the package has functions or objects you want to call. If the package only has code or instances of the pm object, you don't need to declare the method as a variable.

Use the following format to import a package from the Package Library:

const variableName = pm.require('@team-domain/package-name');

variableName.functionName()

Use the following format to import an external package from a package registry:

// package imported from npm
const npmVariableName = pm.require('npm:package-name@version-number');

npmVariableName.functionName()

// package imported from jsr
const jsrVariableName = pm.require('jsr:package-name@version-number');

jsrVariableName.functionName()

Using global objects

Postman supports the following JavaScript objects globally in your scripts:

Using external libraries

To use a library, require the module by passing its name, and assign the returned exported module content to a variable.

require(moduleName: string): any

The require method enables you to use the sandbox built-in library modules. The list of available libraries is below with links to the corresponding documentation.

The following libraries are deprecated and no longer supported:

The following NodeJS modules are also available to use in the sandbox:

Postman doesn't support the following in the buffer module: isAscii, isUtf8, resolveObjectURL, transcode, and copyBytesFrom.

Last modified: 2024/10/02