Run Newman (Postman CLI) in TeamCity (CI) with Secrets
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.
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:
- Keep secrets in TeamCity;
- Run TeamCity build;
- Get secrets from the environment variable and generate
globals.json
for Newman as a build step; - Run Newman as a build step.
Fig. 1. Testing flow
Create Scripts
1. Understand the structure of My_Workspace.postman_globals.json
file:
Postman → Environments → Globals → Export
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.
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.
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]
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.
Fig. 6. Environment Variable (env.) and hidden value
Add Build Steps
On each step I run one script file by Node.js.
Fig. 7. Build Step (2 of 3): Generate globals for Newman
Fig. 8. Build Step (3 of 3): Run Newman
Fig. 9. Build Steps
When you [Run] build, everything should work.
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