Sometimes, as a test engineer, you need to run your tests in CI with secret tokens.

Postman is a perfect tool to start API testing. And Newman is a way to run your Postman collections on the command line. With Newman, you can easily run tests in your own CI tool: TeamCity, Jenkins, and so forth.

Run Newman in TeamCity with Secrets

Despite the fact that Postman and Newman allow you to keep variables in different scopes, there is a security case, when you are not allowed to store data (passwords, tokens, or any authentication credentials) in plain text.

If you put a token in Postman’s Globals or Environment variables and export variables into a file (for further use by Newman), your token’s value will be in plain text. Everyone with access to these files could see and exploit it.

To eliminate security-related risks, you can keep secrets inside CI tools. For example, TeamCity allows to hide the actual value of a variable through Typed Parameters.

The idea looks simple:

  1. Keep secrets in TeamCity;
  2. Run TeamCity build;
  3. Get secrets from the environment variable and generate globals.json for Newman as a build step;
  4. Run Newman as a build step.

alt_text

Fig. 1. Testing flow

Create Scripts

1. Understand the structure of My_Workspace.postman_globals.json file:

Postman → Environments → Globals → Export

postman_globals.json file

Fig. 2. postman_globals.json file — as noted above, you can see the token’s value in plain text

This JSON you need to generate.

2. Write a script that generates the same JSON structure, pull the required environment variable and, add it to the JSON, create a file:

const fs = require('fs');

let date = new Date();
let dateIso = date.toISOString();

// The structure of postman_globals.json file
let postmanGlobals = {
  "id": "146e52f0-fd32-4814-8e58-8a3c0f4d5eb7",
  "values": [
	  {
  	  "key": "token",
  	  "enabled": true
	  }
  ],
  "name": "My Workspace Globals",
  "_postman_variable_scope": "globals",
  "_postman_exported_at": dateIso,
  "_postman_exported_using": "Postman/9.0.3"
}

// Access to environment variable and add it to object postmanGlobals
postmanGlobals.values[0].value = process.env.TOKEN;

// Create globals.json file containing object postmanGlobals as a string
fs.writeFile("globals.json", JSON.stringify(postmanGlobals), (err) => {
  if (err) throw err;
});

3. Export Postman Collection (*.postman_collection.json file).

My test collection is based on one handler of OpenWeather API. It requires a token to respond with 200 OK.

Test collection

Fig. 3. Test collection

4. Write a script which runs Newman as a library:

// https://www.npmjs.com/package/newman#using-newman-as-a-library
const newman = require('newman');

newman.run({
  collection: require('./my.postman_collection.json'),
  globals: require('./globals.json'),
  reporters: 'cli'
}, (err) => {
  if (err) throw err;
});

5. Test your scripts locally before running them in CI.

Newman’s local testing

Fig. 4. Newman’s local testing

To test local access to the environment variable, you need to add a token to the shell environment:

export TOKEN={your_secret_token}

Create Build

Creating a build configuration in TeamCity is a quite nontrivial process. I will show only the parts related to the Newman run.

Add Token

In TeamCity build configuration → Parameters → [Add new parameter]

Add new parameter

Fig. 5. Add new parameter

Fill in the fields:

  • Name = env.TOKEN
  • Kind = Environment variable (env.)
  • Value = {your_secret_token}
  • Spec → click [Show raw value] = password display='hidden' readOnly='true'

After [Save], your variable’s value will be hidden.

Environment Variable and hidden value

Fig. 6. Environment Variable (env.) and hidden value

Add Build Steps

On each step I run one script file by Node.js.

Build Step (2 of 3): Generate globals for Newman

Fig. 7. Build Step (2 of 3): Generate globals for Newman

Build Step (3 of 3): Run Newman

Fig. 8. Build Step (3 of 3): Run Newman

Build Steps

Fig. 9. Build Steps

When you [Run] build, everything should work.

Success

Fig. 10. Success

For the reason that all private data is separate from the code, I post the example on GitHub without fear of token leaks.

Copy @ Medium