Write API Tests with Postman and Newman

Ganga Chris

Software testing is a common practice these days in many organisations, and for even individual developers. Googling around, you'll find a number of types of software tests that exist to help with this.

Postman is a good tool which we mostly use to quickly test APIs to see the result returned by them, but it's actually way more powerful than that.

Postman Features

To mention a few of the features it comes with:-

  1. You can simply test any API and see the response immediately.
  2. You can create a collection of API endpoints and call them whenever you want to see the responses.
  3. You can share these collections, when you are logged in with team members.
  4. You can use Postman's CLI client, Newman, to write Postman tests with JavaScript.
  5. You can write tests in JavaScript to test the response that comes when a Postman request is made.
  6. Finally, once you have all these endpoints created, you can export a JSON file, both for the endpoint tests and the environment variables, which again can be used by Postman as a source of for the tests.

We are going to look at all these feature, some are intuitive, some not so much unless you've been using Postman for a while.

Since Postman is a tool, we can test APIs written in any language, we'll do our tests with the open Github API.

Installation and Setup

If you have Postman already installed, you can skip to the next section.

If not, make sure you have Google Chrome installed, then head over to the Chrome Store and search for Postman Install it by clicking the Add to Chrome button, then it will either turn to Launch App or take you to the Google Chrome Apps page. You can open it with either options.

NOTE: Google will be phasing out Chrome apps on the Chrome Web Store by 2018. So it's encouraged to install the native Postman for your platform. Visit the Postman site and get your platform download. You can then look it up in your installed apps and open it.

You can choose to Sign Up if you want, this is important especially for saving your API collections and accessing them anytime on any machine, but for this article, we can skip this. There's a button for that towards the bottom when you first launch the app.

Postman Collections

There's a Collections tab on the top left of Postman, with an example POSTMAN Echo collection. You can open and inspect it. From the above screen shot, I've selected one of the API requests from the collection, and navigated to it's test tab.

The code you see there starting with tests["response code is 401"] = responseCode.code === 401; is just JavaScript, and this is actually how we are going to write our tests for the Github API I had mentioned earlier.

You can open the other API requests in the POSTMAN Echo collection to have a feel of how requests are made.

So let's start by making our own collection, and call it Github API. Click on the Add Collection button on the top left of Postman You will be prompted to give details about the collection, I've added a name Github API and given it a description. Clicking on Create should add the collection to the left pane, above, or below the example POSTMAN Echo collection.

We'll then add a folder to the collection. Folders are a great way of separating different parts of your API workflow. I called the folder Github Root API and again gave a description.

Now that we have the folder, the next task is to add an API call that is related to the Github API root to that folder. That API call is to https://api.github.com/.

If you still have one of POSTMAN Echo collections open, you can close it the same way you close tabs in a browser, or just click on the plus button to add a new tab on the right pane where we make requests. Type in or paste in https://api.github.com/ and press Send to see the response. Once you get the response, you can click on the arrow next to the the save button on the far right, and select Save As, a pop up will be displayed asking where to save the API call. Give a name, it can be the request URL, or a name like Root API Request, and a description, then choose the collection and folder, in this case Github API > Github Root API, then click on Save. The API call will be added to the Github Root API folder on the left pane. Whenever you click on this request from the collection, it will open in the center pane.

Let's Write the First Test

We've seen that the Root API Request request has a JSON response, which is usually the case for most APIs. The response has properties such as current_user_url, emails_url, followers_url and following_url to pick a few.

The current_user_url has a value of https://api.github.com/user. Say we want to write a test for this.

Click on the Root API Request and click on the test tab in the section just below where the URL is put.

You'll notice on the right pane, we have some snippets which Postman creates when you click so that you don't have to write a lot of code. I've annotated the relevant one for this test, which is Response Body: JSON value check. Clicking on it produces the following snippet.

var jsonData = JSON.parse(responseBody);
tests["Your test name"] = jsonData.value === 100;

From above, we can tell that Postman stores the response in an object called responseBody, and we can use this to assert values.

Postman has another global variable object called tests, which is an object you can use to name your tests, and equate it to a boolean expressions. If the boolean expression returns true, then the test passes.

tests['some random test'] = x === y

If you click on Send to make the request, you will see a one of the tests failing.

Edit the snippet to make it relevant to our test.

var jsonData = JSON.parse(responseBody);
var usersURL = "https://api.github.com/user"
tests["Gets the correct users url"] = jsonData.current_user_url === usersURL;

Clicking on send, you'll see the test passing. .

Let's modify the test further to test some of the properties we want to check.

const jsonData = JSON.parse(responseBody);
const usersURL = "https://api.github.com/user"
const emailsURL = "https://api.github.com/user/emails"
const followersURL = "https://api.github.com/user/followers"
const followingURL = "https://api.github.com/user/following{/target}"

let {current_user_url, emails_url, followers_url, following_url} = jsonData

// Tests go here
tests["Gets the correct users url"] = current_user_url === usersURL;
tests["Gets the correct emails url"] = emails_url === emailsURL;
tests["Gets the correct followers url"] = followers_url === followersURL;
tests["Gets the correct following url"] = following_url === followingURL;

This is just JavaScript. To spice it up, we've used Destructuring Assignment in ES2015, to declare the jsonResponse variables we're interested in.

Clicking on Send should return success, and the tests passing.

Remember to click on Save, so that your test is saved to the request created in the collection.

Environment Variables

Most of the time while writing tests, we usually do not want to go around editing values that we either send as query or post parameters. That way, for instance, if we have ten requests which all send the username scotch-io, we need to create a variable for this so that we can change it once.

Let's create another request called User Details Request, which will make a request with a username. Following the same procedure we did for the Root API Request, create a folder called Github User Details, and add the request inside it. Make the GET request to https://api.github.com/users/scotch-io Now, we want to take make both https://api.github.com/users/ and scotch-io environment variables. To do this click on the top right gear icon, then select Manage Environments A pop up will be displayed. Below it, under the Manage Environments tab click on Add. Give your environment a name. I gave it the name GITHUB_ENV, and set up the environment variables you want as key value pairs. In this case we have USERS_URL and USERNAME.

Once you are done, click on the Add button and close the dialog. Next, select the environment you just created from the top right drop down. Once selected, you can confirm the values by clicking on the eye-like icon, just before the settings/gear icon.

NOTE: Make sure the USERS_URL doesn't have an extra slash / at the end. (I made that mistake). You can click on the eye icon, and click on edit to change it.

Now go back to the GET request, and replace the values with angular-like or laravel-blade like template strings, {{USERS_URL}}/{{USERNAME}}.

In a nutshell, that's how environment variables are added and used in Postman. You can use the same two calibraces syntax to add query parameters and post parameters.

As an example, if the above request took query parameters, we'd have something similar to this, {{USERS_URL}}/{{USERNAME}}?query={{SOME_QUERY}}

Let's add two tests to wrap up this request.

const jsonData = JSON.parse(responseBody);

const { login } = jsonData;

tests["Gets the correct username"] = login === "scotch-io";

tests["Status code is 200"] = responseCode.code === 200;

tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");

I've used responseCode.code and postman.getResponseHeader which are global variables and methods which come with Postman. You can read more about them here

To get a bit fancy, you can use a test, to set an environment variable. If you look at the snippets provided when you go to the tests tab in the request area, you'll see a set environment variable snippet which looks like this postman.setEnvironmentVariable("variable_key", "variable_value");.

We could therefore set an environment variable, and then use it in subsequent requests. A good example for this is getting an authentication token and using it as a header or query parameter for subsequent requests.

Newman CLI

Once you've set up all your collections and written tests for them, it may be tedious to go through them one by one, clicking send to see if a given collection test passes.

This is where Newman comes in.

Newman is a command-line collection runner for postman

All you need to do is export your collection and the environment variables, then use Newman to run the tests from your terminal.

NOTE: Make sure you've clicked on Save to save your collection first before exporting.

So the first step is to export your collection and environment variables. Click on the Menu icon for Github API collection, and select export Select version 2, and click on Export Save the JSON file in a location you can access with your terminal. I created a directory called postman and saved it there.

Next, click on the settings/gear icon and select Manage Enironments again, then click on the download icon to download the GITHUB_ENV environment Save the file in the same directory as the collection.

Install Newman CLI globally, then navigate to the where you saved the collection.

npm install -g newman
cd postman

Using Newman is quite straight foreward, and the documentation is extensive. You can even require it as a Node.js module and run the tests there. We'll however use the CLI.

Once you are in the directory, run newman run <collection_name.json>, replacing the collection_name with the name you used to save the collection.

newman run Github\ API.postman_collection.json

The result for this is We can see the second API test Github User Details fails, and towards the bottom there's an error message Invalid URI "http:///%7B%7BUSERS_URL%7D%7D/%7B%7BUSERNAME%7D%7D".

This is because we did not specify the environment file. To fix it, simply add the -e flag which stands for the environment and add the environment file.

newman run Github\ API.postman_collection.json -e GITHUB_ENV.postman_environment.json

Conclusion

Postman and Newman can be used for a number of test cases, including creating usage scenarios for your API. You can create a scenario that involves a user registering, logging in and calling different endpoints by using a straight foreward user interface. These collections can then be exported and shared with team members. If you create a team account, you can just publish them to your team mates.

Happy Testing!

Ganga Chris

I'm a Full Stack Developer at Andela (Mostly JavaScript & Go). Recently got into Blockchain tech.