Skip to content

Automated API Testing with Postman & Newman — Complete Guide

DodaTech Updated 2026-06-24 5 min read

In this tutorial, you'll learn about Automated API Testing with Postman & Newman. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Automated API testing uses Postman collections and Newman CLI to validate endpoints, check responses, and catch regressions by running test suites in CI pipelines.

What You'll Learn

You will learn how to write API tests in Postman, run them programmatically with Newman, integrate into CI/CD pipelines, and generate HTML reports. This tutorial uses DodaTech's Durga Antivirus Pro threat intelligence API as the running example.

Why Automated API Testing Matters

Manual API testing does not scale. When you have hundreds of endpoints, every deployment risks breaking something. Automated tests catch regressions before they reach users. DodaTech's Durga Antivirus Pro runs 2,000+ API tests per deployment across its threat intel, license validation, and device sync endpoints.

Setting Up Postman Tests

Postman tests are JavaScript snippets that run after the response arrives. They live in the Tests tab of a request or collection.

// Tests tab — validate response structure and content
pm.test("Status code is 200", function () {
  pm.response.to.have.status(200);
});

pm.test("Response has threat data", function () {
  const json = pm.response.json();
  pm.expect(json).to.have.property("threats");
  pm.expect(json.threats).to.be.an("array");
});

pm.test("Threat items have required fields", function () {
  const json = pm.response.json();
  json.threats.forEach(function (threat) {
    pm.expect(threat).to.have.all.keys(
      "id", "name", "severity", "detected_at"
    );
  });
});

Expected output in Postman test runner:

PASS Status code is 200
PASS Response has threat data
PASS Threat items have required fields

Collection Runner with Data Files

Use CSV or JSON data files to run the same test against multiple inputs.

# threats.csv
endpoint,expectedCount
/threats/malware,5
/threats/phishing,3
/threats/ransomware,2
// Collection-level pre-request script
const endpoint = pm.iterationData.get("endpoint");
const expectedCount = pm.iterationData.get("expectedCount");
pm.request.url = pm.request.url + endpoint;

pm.test("Returns expected number of threats", function () {
  const json = pm.response.json();
  pm.expect(json.threats.length).to.eql(expectedCount);
});
# Run with data file
newman run durga-threat-intel.postman_collection.json \
  -d threats.csv \
  --reporters cli,htmlextra

Expected CLI output:

→ /threats/malware
  ✓ Returns expected number of threats
→ /threats/phishing
  ✓ Returns expected number of threats
→ /threats/ransomware
  ✓ Returns expected number of threats

┌─────────────────────────┬──────────┬──────────┐
│                         │ executed │  failed  │
├─────────────────────────┼──────────┼──────────┤
│              iterations │        3 │        0 │
├─────────────────────────┼──────────┼──────────┤
│                requests │        3 │        0 │
├─────────────────────────┼──────────┼──────────┤
│            test-scripts │        6 │        0 │
├─────────────────────────┼──────────┼──────────┤
│      prerequest-scripts │        3 │        0 │
├─────────────────────────┼──────────┼──────────┤
│              assertions │        6 │        0 │
├─────────────────────────┼──────────┼──────────┤
│ total run duration: 423ms │         │         │
└─────────────────────────┴──────────┴──────────┘

CI/CD Integration with Newman

Add API tests to your GitHub Actions pipeline.

# .github/workflows/api-tests.yml
name: API Tests
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm install -g newman newman-reporter-htmlextra
      - name: Run API tests
        run: |
          newman run tests/durga-api.postman_collection.json \
            --environment tests/prod.postman_environment.json \
            --reporters cli,htmlextra \
            --reporter-htmlextra-export reports/api-report.html
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: api-test-report
          path: reports/

Expected CI output:

Run newman run tests/durga-api.postman_collection.json
✔ All tests passed (24/24 assertions)
✔ HTML report generated: reports/api-report.html

Chained Requests and Dynamic Variables

Real APIs often require auth tokens, session IDs, or dependent data.

// Login request — Tests tab
pm.test("Login succeeds", function () {
  const json = pm.response.json();
  pm.expect(json).to.have.property("access_token");
  // Save token for subsequent requests
  pm.collectionVariables.set("auth_token", json.access_token);
});

// Subsequent request — uses the saved token
pm.test("Fetch threat list with auth", function () {
  pm.expect(pm.collectionVariables.get("auth_token")).to.not.be.empty;
});
flowchart LR
    A["Postman Collection\nWrite Tests"] --> B["Export Collection + Env"]
    B --> C["Run with Newman\nLocally"]
    C --> D{"All Tests Pass?"}
    D -->|Yes| E["CI Pipeline\nGitHub Actions"]
    D -->|No| F["Fix & Re-run"]
    E --> G["HTML Report\nGenerated"]
    G --> H["Deploy to Prod"]
    style A fill:#dbeafe,stroke:#2563eb
    style C fill:#bbf7d0,stroke:#16a34a
    style E fill:#fef3c7,stroke:#d97706

Common Errors

1. Assertions Pass But the Endpoint Is Wrong

The test passes because the response has the right shape but the status code is 200 for error responses. Always check pm.response.to.have.status(200) first.

2. Hardcoding Environment URLs

Hardcoded URLs break when switching between dev, staging, and prod. Use Postman environment variables and --environment flag with Newman.

3. Not Handling Async Responses

Some endpoints return 202 Accepted with a job ID. Poll the status endpoint in your test collection rather than asserting the final result immediately.

4. Running Tests Against Live Data

Tests that create, update, or delete data can corrupt production. Use isolated test environments or seed-and-teardown patterns.

5. Ignoring Test Failures in CI

A failing API test should block the pipeline. Do not use continue-on-error: true for API tests unless the endpoint is explicitly unstable.

Practice Questions

1. How do you pass data between requests in a Postman collection?

Use pm.collectionVariables.set("key", value) in the Tests tab of the first request, and pm.collectionVariables.get("key") in subsequent requests.

2. What Newman flag runs tests with a CSV data file?

-d filename.csv or --iteration-data filename.csv.

3. How do you generate an HTML report from Newman?

Install newman-reporter-htmlextra and run with --reporters cli,htmlextra --reporter-htmlextra-export report.html.

4. What is the difference between collection variables and environment variables?

Collection variables are scoped to the collection and shared across environments. Environment variables change per deployment (dev, staging, prod).

5. Challenge: Write a Postman test that validates response time is under 500ms for a threat search endpoint.

pm.test("Response time under 500ms", function () {
  pm.expect(pm.response.responseTime).to.be.below(500);
});

Mini Project: Threat Intel API Test Suite

Create a Postman collection that tests DodaTech's Durga Antivirus Pro threat intelligence API: login, fetch threat list, search by severity, paginate results, and validate each response schema. Run it with Newman against a staging environment and generate an HTML report.

Related Tutorials

RESTful API DesignCI/CD Pipeline Setup — API Gateway Patterns


Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-24.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro