Loops and Dynamic Variables in Postman: Part 2

A series that explores how to loop over tests with dynamic data in Postman.

In part one, we explored some of the fundamental topics of Postman including environment variables, storing and parsing typed variables and controlling test flow. In this post, we are going to put all that together and show some examples of creating loops using Postman requests.

I will be using dummy JSON data from jsonplaceholder.typicode.com in this article so you can follow along. It is seeded with “posts”, “users” and “comments” which doesn’t make for very interesting examples, but it will help illustrate how to use loops.

To import the collection and run yourself, you can use this link: https://www.getpostman.com/collections/e8931613219d3b7a02e2.

Looping Over Data in a Single Test

Let’s imagine our API exposes an endpoint /posts that returns a list of posts with a GET:

[
  {
    "userId": 1,
    "id": 1,
    "title": "test post 1",
    "body": "test post 2"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "test post 2",
    "body": "test post 2"
  }
]

We may want to validate that each post conforms to a schema using Tiny Validator:

var jsonData = JSON.parse(responseBody);

var schema = {
  "properties": {
    "userId": {
      "type": "integer"
    },
    "id": {
      "type": "integer"
    },
    "title": {
      "type": "string"
    },
    "body": {
      "type": "string"
    }
  },
  "required": ["userId", "id", "title", "body"]
};

jsonData.forEach(function(post) {
    var testTitle = "Post " + post.id + " conforms to schema";
    tests[testTitle] = tv4.validate(post, schema);
});

Example Loop

Looping over data works really well when your API returns a list of objects and you want to validate that each matches a similar set of conditions.

Looping Over Data That Requires Additional Requests

What if we get a list of posts and we want to iterate over each post, retrieving a child path that contains some data about that post? For example, GET /posts returns the list of all posts. GET /posts/1/comments returns a list of all comments associated with that post. We want to loop over all posts and verify that each comment has a non-empty name, email, and body. Creating a test for each post is hardly maintainable and for most systems, it’s impossible to know the generated ID for a post (or whatever the resource may be).

We can use environment variables and alter the test flow to effectively loop over each post ID and test it’s comments. The flow looks like the following:

  1. Retrieve the list of posts (GET /posts)
  2. Create and store a list of post IDs as an environment variable (postIDs)
  3. Set the postID variable to the first item in the list
  4. Use postman.setNextRequest() to call GET /posts//comments
  5. Validate the response
  6. Retrieve the list of post IDs from the environment
  7. Pop the next post ID from the list and set the postID environment variable
  8. Overwrite the environment variable postIDs with the updated list
  9. Use postman.setNextRequest() to call GET /posts//comments again

There’s a lot going on there. Essentially we are use postIDs as a loop control, popping an ID off of the list and setting postID to it’s value, then storing the list again, this time with one less item. We call the same test with postman.setNextRequest(), but with different environment variables set, thus creating the loop. Before we dive in, it’s important to know how the requests are ordered in the collection:

Request Order

Let’s take a look at the first test that starts this process off, GET /posts:

Get Posts

After running this request, the environment variables will be populated:

Env Vars

Now we can call GET /posts//comments which looks like the following:

Get Post Comments

Ignoring the schema tests, the bottom part of the test is what actually controls our loop. We get the stringified postIDs list from the environment and parse it back into a list. If the list is not empty, then we need to update the variables and call it again with the updated information. That requires getting the first element from the list (postIDs.shift()) and setting it to postID in our environment. Then we overwrite the postIDs environment variable with our updated, stringified list. Lastly, we call the same request, thus making the loop. Once there are no more items in the postIDs list, we will clear the postID and postIDs environment variables and simply continue on in our request execution with the next test (in this case, GET /users).

To give you an idea of what the second iteration of the loop looks like, here are the environment variables after having run GET /posts//comments for the first time:

Env Vars

Let’s put all this together and let the Collection Runner run our requests:

Collection Runner Execution

You can see that 722 tests have passed and that GET /posts was executed first (populating the environment variables) and then all the iterations of GET /posts//comments. Once we exhausted the list of post IDs, we can see that test flow resumed as expected:

Collection Runner Execution

Summary

There you have it. By using environment variables to control your loop and set the parameters for your tests, you can effectively create dynamic loops with Postman. Because I wanted to provide an example using a public API, the example may seem a little contrived. I should point out that we could have requested GET /comments (which returns all comments for all posts) and validated comments that way with the first loop method discussed. But for situations where you need to issue subsequent requests for data, loops can be a helpful tool.