Writing Tests in Postman

Using postman we also can write test cases or build request using java script code. This code can use dynamic parameters, variables, or pass data between different requests. It allows us to write javascript code at two events:

  1. Before request sent to server, we call it Pre-request script and can be written in Pre-request Script
  2. After response is received from request, we call it test script. It lies under Test Script

Script can be written at Collection, Folder or request level so questions comes what will be order of execution. To understand that let’s see this picture:

Here I am describing test cases using newer PM API (pm.* API). Though Postman still supports old postman API but we should use newer one so that in case postman deprecate old API we don’t need to invest in maintenance.

In previous article I already covered logging options in Postman which can be used in both Pre Request and Test script. Use console for debugging.

Using PreRequest Script

In case request is need to required input which will be served from previous request in that case we can first check if required value is populated or not. If value is available then only request should be sent else move to next request.

if (!pm.environment.has("auth-token"))
{
    console.log("Stopping the test as AuthToken not found.");
    postman.setNextRequest(null);
}

As we used setNextRequest so lets discuss it in details. We can set any valid request name or null. In case of null execution will be stopped. If we pass any request name (like postman.setNextRequest(“request_name”)) then named request will be executed. There are some important facts which we need to consider before using setNextRequest.

  • setNextRequest() is always executed at the end of the current script. This means that if you put setNextRequest() before other code blocks, these blocks will still be executed.
  • setNextRequest() has a scope, which is the source of your collection run. This means that if you run a collection, you can jump to any request in the collection (even requests inside folders, using the same syntax). However, if you run a folder, the scope of setNextRequest() is limited to that folder only.

Using Test Script

Pm.test()

This is main function used for writing the test cases. This function accepts 2 parameters, the name of the test (as a string) and a function to return a boolean value. It can be used only in the Tests tab, after the primary Postman request has been sent.

// example using pm.response.to.have
pm.test("response is ok", function () {
    pm.response.to.have.status(200);
});

// example using response assertions
pm.test("response should be okay to process", function () { 
    pm.response.to.not.be.error; 
    pm.response.to.have.jsonBody(""); 
    pm.response.to.not.have.jsonBody("error"); 
});

pm.expect()

The pm.expect() assertion function was built on the shoulders of the popular JavaScript test library ChaiJS BDD. Using a similar syntax, pm.expect() makes it easy to write readable tests, and you can deal with assertions of data from a response or variables.

// example using pm.expect()
pm.test("environment to be production", function () { 
    pm.expect(pm.environment.get("env")).to.equal("production"); 
});

pm.response.to.be.*

The pm.resonse.to.be object provides shorthands for frequently used response based checks. Using this family of assertions streamlines tests for response status types and body variations.

// example using pm.response.to.be*
pm.test("response must be valid and have a body", function () {
     // assert that the status code is 200
    // info, success, redirection, clientError,  serverError, are other variants
pm.response.to.be.ok;
   // this assertion also checks if a body exists,
pm.response.to.be.withBody;
     // assert that the response has a valid JSON body
pm.response.to.be.json; 
});

You can see the script result in result section under Test Results tab. In parenthesis it will show Pass Test Cases/Total count of test cases.

Postman makes the process of writing test script easier by listing commonly used snippets next to the editor. You can select the snippet you want to add and the appropriate code will be added to the test editor.

How advanced is your team when it comes to testing?

Writing tests – Most people agree that writing tests is important, but writing the first test is sometimes the biggest hurdle to testing. Once you’ve written your first test, every subsequent step becomes infinitely more manageable.

Code snippets – The first step is to use code snippets. These stubs demonstrate how a Postman test runs, how they’re structured, and show test results.

Custom tests – The next step is to write your own custom tests. Use JavaScript to address common user flows and edge cases unique to your endpoints.

Run the collection – Now it’s time to run your requests, along with their respective tests, together as a collection. There are several ways to run your tests – e.g. Postman’s collection runner, Postman’s command line tool Newman, or with a Postman scheduled monitor.

CI / CD integration – If your team is churning out code, the last thing you want to do is manually run these tests every time someone has a bug fix or feature update. When in doubt, automate!

If you haven’t progressed to Step 5, keep investing in testing.

Let’s start with understanding more about variables:

string
When a variable’s type is set to “string”, it ensures that Variable#get converts the value of the variable to a string before returning the data.

boolean
A boolean type of variable can either be set to true or false. Any other value set is converted to Boolean when procured from Variable#get.

number
A “number” type variable ensures that the value is always represented as a number. A non-number type value is returned as NaN.

json
A “json” type value stores JSON data format

any
Free-form type of a value. This is the default for any variable, unless specified otherwise. It ensures that the variable can store data in any type and no conversion is done while using Variable#get.

Here is example to verify the data type:

var jsonData = JSON.parse(responseBody);
//console.log ("Data type:" + typeof(jsonData));
// All data types: number, boolean, string, json, any
tests["Age is number"] = typeof(jsonData.age) === "number";
tests["Name is string"] = typeof(jsonData.name) === "string";

Here are some more examples from postman site:

Setting an environment variable

pm.environment.set("variable_key", "variable_value");

Setting a nested object as an environment variable

var array = [1, 2, 3, 4];
pm.environment.set("array", JSON.stringify(array, null, 2));

var obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
pm.environment.set("obj", JSON.stringify(obj));

Getting an environment variable

pm.environment.get("variable_key");

Getting an environment variable (whose value is a stringified object)

// These statements should be wrapped in a try-catch block if the data is coming from an unknown source.

var array = JSON.parse(pm.environment.get("array"));
var obj = JSON.parse(pm.environment.get("obj"));

Clear an environment variable

pm.environment.unset("variable_key");

Set a global variable

pm.globals.set("variable_key", "variable_value");

Get a global variable

pm.globals.get("variable_key");

Clear a global variable

pm.globals.unset("variable_key");

Get a variable

This function searches for the variable across globals and the active environment.

pm.variables.get("variable_key");

Check if response body contains a string

pm.test("Body matches string", function () {
    pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});

Check if response body is equal to a string

pm.test("Body is correct", function () {
    pm.response.to.have.body("response_body_string");
});

Check for a JSON value

pm.test("Your test name", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(100);
});

Content-Type is present

pm.test("Content-Type is present", function () {
    pm.response.to.have.header("Content-Type");
});

Response time is less than 200ms

pm.test("Response time is less than 200ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(200);
});

Status code is 200

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

Code name contains a string

pm.test("Status code name has string", function () {
    pm.response.to.have.status("Created");
});

Successful POST request status code

pm.test("Successful POST request", function () {
    pm.expect(pm.response.code).to.be.oneOf([201,202]);
});

Use TinyValidator for JSON data

var schema = {
 "items": {
 "type": "boolean"
 }
};
var data1 = [true, false];
var data2 = [true, 123];

pm.test('Schema is valid', function() {
  pm.expect(tv4.validate(data1, schema)).to.be.true;
  pm.expect(tv4.validate(data2, schema)).to.be.true;
});

Another example for TinyValidator with complex JSON

var schema = {
  "properties": {
    "environments": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "owner": {
              "type": "string"
            },
            "uid": {
              "type": "string"
            }
          },
          "required": [
            "id",
            "name",
            "owner",
            "uid"
          ]
        },
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "owner": {
              "type": "string"
            },
            "uid": {
              "type": "string"
            }
          },
          "required": [
            "id",
            "name",
            "owner",
            "uid"
          ]
        }
      ]
    }
  },
  "required": [
    "environments"
  ]
};
var response = {
    "environments": [
        {
            "id": "76823b7e-7bd3-13a9-3472-215f39d5bdb8",
            "name": "STE",
            "owner": "2990698",
            "uid": "2990698-76823b7e-7bd3-13a9-3472-215f39d5bdb8"
        },
        {
            "id": "8476b71e-6308-c1ff-909e-b3d5a03061d3",
            "name": "Dev",
            "owner": "2990698",
            "uid": "2990698-8476b71e-6308-c1ff-909e-b3d5a03061d3"
        }
    ]
};
pm.test('Schema is valid', function() {
  pm.expect(tv4.validate(response, schema)).to.be.true;
  console.log("Schema is valid");
});

TIP: You can use online tools (For ex: https://www.liquid-technologies.com/online-json-to-schema-converter) to create JSON schema from json output.

In next article we will discuss how to use collections effectively.

17 thoughts on “Writing Tests in Postman

  1. Rajendra says:

    How to pass variable data in JSON input?

  2. Satyavan Verma says:

    Pass Variable name in double quotes.

    { 
     "request": { 
       "UUID":"{{$guid}}",
       "firstName":"Satyavan",
       "lastName":"Verma",
       "Timestamp":"{{$timestamp}}" 
      }
    }
  3. Paul says:

    I have a GET request XML with parameters (no request body) which I have parameterrized and able to send the request with multiple data sets using csv file (using collection runner). But I need to save the responses for each request, but I am not sure how to do it using a script. I need to save response in XML format to local drive. Can you please help me?

  4. Ourhints says:

    Sorry for late response. This can be best accomplished within Postman’s CLI companion, Newman. You would then write a script to generate your custom reports via the following steps:

    1. Ensure that you have node and npm installed.
    2. Install newman with: npm install newman.
    Create a file with the following contents:

    var fs = require('fs'),
        newman = require('newman'),
    
        results = [];
    
    newman.run({
        reporters: 'cli',
        collection: '/path/to/collection.json',
        environment: '/path/to/environment.json' // This is not necessary
    })
    .on('request', function (err, args) {
        if (!err) {
            // here, args.response represents the entire response object
            var rawBody = args.response.stream, // this is a buffer
                body = rawBody.toString(); // stringified JSON
    
            results.push(JSON.parse(body)); // this is just to aggregate all responses into one object
        }
    })
    // a second argument is also passed to this handler, if more details are needed.
    .on('done', function (err, summary) {
        // write the details to any file of your choice. The format may vary depending on your use case
        fs.writeFileSync('migration-report.json', JSON.stringify(results, null, 4));
    });
    

    Run the file with:
    node script.js # Here, script.js is the file created in the previous step

  5. jhon Smith says:

    What is this “pm”?

    pm.test(“Status code is 200”, function () {
    pm.response.to.have.status(200);
    });

    1. Ourhints says:

      pm is new api for PostMan. It’s same like postman in older version.For ex:

      postman.setNextRequest(null);

  6. Joe says:

    You show how to check for a specific JSON value.
    “`pm.test(“Your test name”, function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(100);
    });“`
    Is there a way to check for a JSON value that should match an environment variable?

  7. Ourhints says:

    You can try:

    pm.test(“Your test name”, function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(pm.environment.get(“variable_key”));
    });

  8. Madina says:

    How to check if particular object in JSON doesnt exist for a particular data?

    My json should not contain a specific key for some types of data. How to check that obj is not present. To check for its presence i used should.not.be.null it works now i want to see that obj should not be present at all

    1. Ourhints says:

      You can try like:

      pm.test("Your test name", function () {
          var jsonData = pm.response.json();
          pm.expect(jsonData.value).to.not.eql(100);
      });

      or

      pm.test("Body matches string", function () {
          pm.expect(pm.response.text()).to.not.include("string_you_want_to_search");
      });
  9. furtdsolinopv says:

    magnificent post, very informative. I wonder why the other experts of this sector don’t notice this. You should continue your writing. I am confident, you’ve a huge readers’ base already!

  10. Long Reichenback says:

    Hey! I know this is somewhat off topic but I was wondering if you knew where I could get a captcha plugin for my comment form? I’m using the same blog platform as yours and I’m having difficulty finding one? Thanks a lot!

  11. Larissa Shickendantz says:

    Nice article. Im really stumped on identifying json values in primitive json in postman. My json return response does not have a node name for every data element – they are declared in the header and then you just get values. For example in the below – I need to test if the 7’th row int he Totals node =’s a specific value. However the test calls for node[number] where it expects you to test for the 7’th total or 6’th total – rather than the 7’th line in the first total. Love if anyone who knows how to do this could let me know.

    “metadata”: {
    “columnNames”: [
    “AssetType”,
    “CustodianAccount”,
    “Strategy”,
    “LongShort”,
    “Symbol”,
    “Description”,
    “Quantity”,
    “NativeCost”,
    “BookCost”,
    “NativeMarketValue”
    ],
    “columnTypes”: [
    “string”,
    “string”,
    “string”,
    “string”,
    “string”,
    “string”,
    “double”,
    “double”,
    “double”,
    “double”
    ],
    “columnTotalMethods”: [
    “null”,
    “null”,
    “null”,
    “null”,
    “null”,
    “null”,
    “sum”,
    “sum”,
    “sum”,
    “sum”
    ]
    },
    “portfolios”: [
    {
    “portfolioName”: “Lossless”,
    “lots”: [
    {
    “data”: [
    [
    “Equity”,
    “355674294”,
    “Unicorn LS”,
    “Long”,
    “A”,
    “Agilent Technologies, Inc.”,
    “100”,
    “5001.2300000000005”,
    “5001.2300000000005”,
    “6100”
    ],
    [
    “Equity”,
    “355674294”,
    “Unicorn LS”,
    “Long”,
    “A”,
    “Agilent Technologies, Inc.”,
    “700”,
    “17570.350000000002”,
    “17570.350000000002”,
    “42700”
    ]

    1. Ourhints says:

      Not very sure about your question. Also when I validated the json posted by you it was hitting error. You can extract JSON array value and play as you wish.

      var data = JSON.parse(responseBody);
      tests [“Verify data”] = data.columnNames[6]=== “Quantity”

      Hope this helps else please reply back.

  12. Marcus Sandiford says:

    I am not certain where you are getting your information, but great topic. I must spend some time finding out more or figuring out more. Thank you for magnificent information I used to be on the lookout for this information for my mission.|

  13. Eekshitha says:

    Hello,

    Cant we take the response from request and copy that to the excel sheet ?

    What i need exactly is, A tool which can take results from collections and write them accurately to respective test case columns in Sheet.

    Please help me with this

Leave a Reply

Your email address will not be published. Required fields are marked *