Postman Collection Runner: CI Integration and Newman CLI
- Collection Runner executes all requests in a collection sequentially with pre/post scripts
- Newman is the CLI equivalent — install with npm and run anywhere
- Data-driven testing uses CSV or JSON files to parameterize requests
- GitHub Actions and Jenkins both support Newman out of the box
- newman-reporter-htmlextra produces rich, shareable HTML reports
From GUI Clicks to Automated Pipelines
If you have ever clicked "Run" in Postman's Collection Runner, you already understand the value: one button executes every request in a collection, evaluates your test scripts, and surfaces pass/fail counts in a clean table. That is great for exploratory sessions, but it cannot run inside a CI pipeline, a Docker container, or a scheduled job. Newman is the bridge between your Postman collection and your automation infrastructure.
This post walks through the full path — from understanding what the GUI runner does internally, to shipping Newman as a step in GitHub Actions and Jenkins, to generating HTML reports your team can actually read.
What the Collection Runner Does vs the GUI
When you open a collection in Postman and hit "Run", the runner:
- Resolves the active environment (variables like
{{baseUrl}},{{token}}) - Executes each request in document order (or a custom order you set)
- Runs Pre-request Scripts before each HTTP call
- Evaluates Test Scripts after each response
- Accumulates pass/fail counts and surfaces them in a results panel
What it does not do: persist state between runs, produce machine-readable output, or integrate with external systems. That is Newman's job.
Key difference: the GUI Collection Runner is synchronous and interactive. Newman is headless, exit-code-aware, and composable with anything that can run a shell command.
Newman CLI: Setup and First Run
Newman requires Node.js 14+. Install it globally:
npm install -g newmanExport your collection from Postman (Collection → ··· → Export → Collection v2.1) and your environment (Environments → ··· → Export). Then:
newman run my-collection.json \
--environment staging.json \
--reporters cliNewman exits with code 0 on success and 1 if any test fails or a request errors out. CI systems treat that exit code as a gate — no extra configuration needed.
Useful flags at a glance:
newman run collection.json \
--environment env.json \
--globals globals.json \ # shared global variables
--iteration-count 5 \ # repeat the full run N times
--delay-request 200 \ # ms between requests
--timeout-request 10000 \ # per-request timeout in ms
--bail \ # stop on first failure
--color onEnvironments and Data Files
Environments (JSON)
An exported Postman environment looks like this:
{
"name": "Staging",
"values": [
{ "key": "baseUrl", "value": "https://api-staging.example.com", "enabled": true },
{ "key": "apiKey", "value": "sk-staging-abc123", "enabled": true }
]
}Pass it with --environment staging.json. Newman resolves {{baseUrl}} and {{apiKey}} throughout every request in the collection.
Data-Driven Testing with CSV
A CSV data file lets you run the same collection multiple times, each time with different variable values. Create users.csv:
username,password,expectedStatus
alice@example.com,secret1,200
bob@example.com,wrongpass,401
charlie@example.com,secret3,200In Postman, reference {{username}} and {{password}} in the request body. In the Test Script, use pm.variables.get("expectedStatus").
Run with the data file:
newman run login-collection.json \
--environment staging.json \
--iteration-data users.csv \
--reporters cliNewman runs the collection once per CSV row — three rows means three iterations.
Data-Driven Testing with JSON
[
{ "productId": "prod_001", "quantity": 1, "expectedTotal": 29.99 },
{ "productId": "prod_002", "quantity": 3, "expectedTotal": 89.97 }
]newman run orders-collection.json \
--iteration-data orders.jsonJSON is preferable when values contain commas or special characters.
GitHub Actions Integration
Create .github/workflows/api-tests.yml:
name: API Tests
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 */6 * * *' # every 6 hours
jobs:
newman:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Newman and reporters
run: npm install -g newman newman-reporter-htmlextra
- name: Run API tests
run: |
newman run postman/collection.json \
--environment postman/staging-env.json \
--reporters cli,htmlextra \
--reporter-htmlextra-export results/report.html \
--reporter-htmlextra-title "API Test Report — ${{ github.sha }}"
- name: Upload HTML report
uses: actions/upload-artifact@v4
if: always() # upload even when tests fail
with:
name: newman-report
path: results/report.html
retention-days: 30A few things worth noting:
- The
if: always()on the upload step ensures you get the report even when Newman exits with code1. - Storing your collection and environment files in the repo (
postman/) keeps everything version-controlled. Sensitive values (API keys) belong in GitHub Secrets, not in the committed environment file — override them with--env-var "apiKey=${{ secrets.STAGING_API_KEY }}".
Override a single variable without editing the environment file:
- name: Run API tests
env:
STAGING_API_KEY: ${{ secrets.STAGING_API_KEY }}
run: |
newman run postman/collection.json \
--environment postman/staging-env.json \
--env-var "apiKey=$STAGING_API_KEY" \
--reporters cli,htmlextra \
--reporter-htmlextra-export results/report.htmlJenkins Integration
In a declarative Jenkinsfile:
pipeline {
agent any
tools {
nodejs 'NodeJS-20'
}
stages {
stage('Install Newman') {
steps {
sh 'npm install -g newman newman-reporter-htmlextra'
}
}
stage('API Tests') {
steps {
withCredentials([string(credentialsId: 'staging-api-key', variable: 'API_KEY')]) {
sh """
newman run postman/collection.json \
--environment postman/staging-env.json \
--env-var "apiKey=${API_KEY}" \
--reporters cli,htmlextra \
--reporter-htmlextra-export results/report.html
"""
}
}
}
}
post {
always {
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'results',
reportFiles: 'report.html',
reportName: 'Newman API Test Report'
])
}
failure {
mail to: 'team@example.com',
subject: "API Tests Failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Check the report: ${env.BUILD_URL}Newman_API_Test_Report"
}
}
}The publishHTML step requires the HTML Publisher plugin. It makes the report browsable directly from the Jenkins build page.
Reporting with Newman HTML Reporter
The default CLI reporter is readable in a terminal but not shareable. newman-reporter-htmlextra produces a full HTML report with request/response bodies, timeline, and filter controls.
Install:
npm install -g newman-reporter-htmlextraRun with multiple reporters simultaneously:
newman run collection.json \
--environment env.json \
--reporters cli,htmlextra,junit \
--reporter-htmlextra-export ./results/report.html \
--reporter-htmlextra-title "Checkout API — Regression Suite" \
--reporter-htmlextra-showOnlyFails \
--reporter-junit-export ./results/junit.xmlThe --reporter-junit-export flag produces a JUnit XML file, which most CI systems (GitHub Actions, Jenkins, GitLab CI) can parse natively to display per-test pass/fail counts in the build dashboard without opening the HTML report.
Key htmlextra flags:
| Flag | Effect |
|---|---|
--reporter-htmlextra-showOnlyFails |
Collapse passing requests — focus on failures |
--reporter-htmlextra-testPaging |
Paginate long test lists |
--reporter-htmlextra-browserTitle |
Browser tab title |
--reporter-htmlextra-logs |
Include console.log output from scripts |
Structuring Collections for CI
A few patterns that make Newman runs predictable in CI:
1. Separate auth into a pre-collection folder. Put your login/token-fetch request first. In its Test Script, extract the token and set it as a collection variable:
const json = pm.response.json();
pm.collectionVariables.set("accessToken", json.access_token);Every subsequent request uses {{accessToken}} in its Authorization header.
2. Clean up after yourself. If your tests create resources (users, orders, products), add a "Teardown" folder at the end that deletes them. This prevents data accumulation across CI runs.
3. Tag slow tests. Newman does not have a native tag system, but you can maintain separate collections — smoke.json (fast, runs on every PR) and regression.json (thorough, runs nightly).
4. Pin your Newman version. Use npm install newman@6.1.0 (pinned) rather than npm install -g newman (latest) to prevent unexpected behaviour from upstream updates.
Wrapping Up
Newman transforms Postman collections from an interactive GUI tool into a first-class CI artifact. The setup is minimal — install Newman, export your collection, add one shell step to your pipeline. From there, data files give you coverage across multiple inputs, environment files handle multi-stage deployments, and HTML/JUnit reporters make results visible to everyone who cares about API quality.
The next step is scheduling: rather than running only on push, consider adding a cron trigger (GitHub Actions schedule, Jenkins cron) so you catch environmental drift between deployments. That is covered in the companion post on Postman Monitors.