Postman Collection Runner: CI Integration and Newman CLI

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:

  1. Resolves the active environment (variables like {{baseUrl}}, {{token}})
  2. Executes each request in document order (or a custom order you set)
  3. Runs Pre-request Scripts before each HTTP call
  4. Evaluates Test Scripts after each response
  5. 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 newman

Export your collection from Postman (Collection → ··· → Export → Collection v2.1) and your environment (Environments → ··· → Export). Then:

newman run my-collection.json \
  --environment staging.json \
  --reporters cli

Newman 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 on

Environments 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,200

In 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 cli

Newman 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.json

JSON 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: 30

A few things worth noting:

  • The if: always() on the upload step ensures you get the report even when Newman exits with code 1.
  • 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.html

Jenkins 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-htmlextra

Run 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.xml

The --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.

Read more

Start now free