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 at which 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.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 at which 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 preinvoke or response depending if the script is executing in Pre-invoke or Response hook respectively.

    pm.info.eventName: 'beforeInvoke' | '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 Pre-invoke or 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 both Before invoke 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');
  });
});

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 NodeJS modules are also available to use in the sandbox:

Last modified: 2024/10/02