spec⟶tests
REV v0.10.0NODE ≥22MIT

openapi-postman-test-generator · cli for node.js

Turn an OpenAPI spec into a running Postman suite.

Point it at a Swagger 2.0 or OpenAPI 3.x document and it generates a full Postman collection — auth, example bodies, JSON Schema assertions, and negative tests — ready to run with Newman.

The generator is deterministic. An optional AI planner may propose operation order and variable mappings — it never writes the Postman scripts.

View source →
bash
$ openapi-postman generate --spec ./petstore.openapi.yaml --negative

Generated 8 requests
Collection:   ./generated/api.collection.json
Environment:  ./generated/api.environment.json

$ openapi-postman run --collection ./generated/api.collection.json

✓ report.html · junit.xml · newman.json
01

Input, process, output.

One route from the fixture used on this page — POST /pets in fixtures/petstore.openapi.yaml — traced from spec to generated request.

Input · openapi.yaml
  /pets:
    post:
      summary: Create pet
      requestBody:
        content:
          application/json:
            schema: { $ref: '#/NewPet' }
      responses:
        '201':
          content:
            application/json:
              schema: { $ref: '#/Pet' }

  NewPet:
    required: [name]
    properties:
      name: { example: Miso }
      status: { enum: [available, adopted] }
⟶
Process · generator.ts
  1. Resolve $ref chains, merge allOf
  2. Merge path + operation parameters
  3. Pick a security scheme, build auth block
  4. Build an example body from the schema
  5. Emit pm.test() assertions
  6. Add negative variants (missing field, invalid enum, unauthorized)
⟶
Output · Postman item
"method": "POST",
"url": "{{baseUrl}}/pets",
"auth": { "type": "bearer" },
"body": {
  "raw": "{ \"name\": \"Miso\",
    \"status\": \"available\" }"
}

// event[0].script.exec
pm.test("Status code is successful (201)", …)
pm.test("Response time is below 2000ms", …)
pm.test("Response matches the schema…", …)
02

One command, a full Postman suite.

The generated collection for the Pets API above, folders and negative tests included — exactly what generate --negative produced for this page.

Pets
POSTCreate pet
POST[Negative] Create pet - unauthorized
POST[Negative] Create pet - missing name
POST[Negative] Create pet - invalid status
GETList pets
GET[Negative] List pets - unauthorized
GETGet pet
GET[Negative] Get pet - unauthorized

openapi-postman run executes the collection with Newman and writes three reports:

report.htmlstandalone, human-readable summary
junit.xmlfor CI test-result panels
newman.jsonraw run data, per-assertion detail
03

Built for real specs, not happy-path demos.

Spec formats
Swagger 2.0 and OpenAPI 3.x, from a local file or a URL
Bodies
JSON, form-urlencoded, multipart uploads, text, and binary responses
Parameters
Path, query, header, cookie, array, and deep-object styles
Auth
Bearer, Basic, API keys, and combined security requirements; --oauth-token starts the run by fetching an OAuth2 client credentials token
Assertions
Status-specific JSON Schema checks, media-type-aware response handling, and the response headers the spec declares (required headers present, sent headers match their schema) — on by default
Ordering & chaining
CRUD-oriented default order, configurable, with identifier extraction between dependent requests
Negative tests
Missing-field, invalid-enum, boundary, and unauthorized cases — optional, off by default
Safe mode
Excludes DELETE operations when testing against an unfamiliar API
Tag filter
--tag keeps the operations that carry one of the tags and --exclude-tag leaves them out; Default names the untagged ones
Coverage
Every run says how many operations have a request and which documented responses have a test; --coverage writes it to a file. coverage --run newman.json says what an actual run passed, failed or never reached
Setup, teardown & polling
Seed and clean-up requests from the project config, and a poll request after an operation that answers with a Location to follow
Runtime values
Named environment profiles, JSON or CSV iteration data, and --env-var KEY=VALUE for values such as an OTP
Runner
Newman execution with CLI, JSON, JUnit, and standalone HTML reports
Bruno & k6
The same tests as a Bruno collection folder (--bruno) and a k6 script (--k6), from generate or from a collection with convert
Spec diff
openapi-postman diff lists what changed between two versions of a spec, response headers included, and exits non-zero on a breaking change
—

Optional: AI-assisted planning

A provider-neutral planner can propose operation order and variable mappings from a read-only prompt, with schema-validated output and automatic fallback between providers. The deterministic generator still writes every Postman script.

OpenAI SDK Codex CLI Claude Code CLI Antigravity CLI Custom command
04

The same run in a pull request.

The GitHub Action generates the collection, writes the coverage to the job summary, runs the tests with Newman and fails the job when a test fails. After the run, the summary also shows what the run covered, and the run-coverage output hands that report to later steps. diff guards the spec itself: it fails the step when the new version breaks clients of the old one.

- uses: vannt-dev/openapi-postman-test-generator@v0.10.0
  with:
    spec: openapi.yaml
    base-url: http://localhost:3000   # optional
    negative: true                    # optional
    exclude-tag: Internal             # optional
$ openapi-postman diff --old ./openapi.main.yaml --new ./openapi.yaml
05

From spec to suite in three commands.

1

Install

$ npm install -g openapi-postman-test-generator
$ npm install -g newman
2

Generate

$ openapi-postman generate --spec ./openapi.yaml --negative --safe
3

Run

$ openapi-postman run --collection ./generated/api.collection.json --environment ./generated/api.environment.json