API Testing in CI/CD: Newman, Jenkins & Debugging Failures
API tests only protect a release if they run automatically — on every commit, every merge and every deployment. This guide shows how to run Postman collections in CI/CD with Newman: the command, pipelines for Jenkins and GitHub Actions, how a failure actually fails the build, and how to debug a run you can only see through CI logs.
The error-handling behavior described was verified by running collections with Newman. For hands-on exercises, see Postman Newman CI/CD Practice.
What Newman Is
Newman is Postman's command-line collection runner. It runs an exported collection — requests, scripts and assertions — without the Postman app, which is exactly what a CI server needs.
Basic Newman Command
npm install -g newman newman-reporter-htmlextra
newman run shop-api.postman_collection.json \
-e qa.postman_environment.json \
--env-var "password=$API_PASSWORD" \
-r cli,junit,htmlextra \
--reporter-junit-export results/newman.xml \
--reporter-htmlextra-export results/newman.html
Important Newman Options
| Option | Purpose |
|---|---|
-e |
Environment file containing the base URL and settings |
--env-var |
Inject a secret at run time instead of storing it in a file |
-d |
Data file for data-driven runs using CSV or JSON |
--folder |
Run one folder only, such as smoke tests |
-r cli,junit,htmlextra |
Console output, JUnit XML for the CI server, and HTML report for people |
--bail |
Stop at the first failure |
--timeout-request 10000 |
Fail requests that hang |
The key CI fact: Newman exits with code 0 when every assertion passes and non-zero when any assertion fails. CI servers treat a non-zero exit code as a failed step — that's what turns a failing API test into a red build.
Jenkins Pipeline
A Jenkins pipeline can install Newman, execute the Postman collection, publish JUnit results and archive the HTML report.
pipeline {
agent any
parameters {
choice(
name: 'ENV',
choices: ['qa', 'staging'],
description: 'Target environment'
)
}
stages {
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('API tests') {
steps {
withCredentials([
string(
credentialsId: 'api-password',
variable: 'API_PASSWORD'
)
]) {
sh '''
npx newman run collections/shop-api.json \
-e environments/${ENV}.json \
--env-var "password=$API_PASSWORD" \
-r cli,junit,htmlextra \
--reporter-junit-export results/newman.xml \
--reporter-htmlextra-export results/newman.html
'''
}
}
}
}
post {
always {
junit 'results/newman.xml'
archiveArtifacts \
artifacts: 'results/*.html',
allowEmptyArchive: true
}
}
}
Keep the collection and environments in the same Git repository as the pipeline, so changes are reviewed and versioned.
Trigger the job on every push or pull request using a webhook, and run the API tests after each deployment to QA.
For more Jenkins guidance, see The Complete Jenkins Tutorial.
GitHub Actions
GitHub Actions can run Newman automatically whenever code is pushed or a pull request is opened.
name: API tests
on:
push:
pull_request:
jobs:
newman:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: |
npx newman run collections/shop-api.json \
-e environments/qa.json \
--env-var "password=${{ secrets.API_PASSWORD }}" \
-r cli,junit \
--reporter-junit-export results/newman.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: newman-results
path: results/
The API_PASSWORD value is stored as a GitHub Actions secret rather than being committed to the repository.
Where API Tests Fit in the Pipeline
API tests can be placed at different stages depending on their execution time and purpose.
- On every commit or pull request: Run a fast smoke folder such as
--folder Smokeagainst a test environment or mocks. - After deploying to QA: Run the full functional and negative API suite.
- Before promoting to staging or production: Run the critical-path collection as a release gate.
- On a schedule: Run nightly regression tests or use Postman Monitors for health checks.
Decide which requests and checks belong in each stage using the API Testing Scenario Lab.
Debugging a Failed CI Run
When an API test fails in CI, the first challenge is identifying whether the problem is with the API, test data, configuration, authentication or the pipeline itself.
1. Read the Failure Summary
Newman lists failed assertions together with information such as:
- Request name
- Assertion name
- Error type
- Assertion error
- Request execution details
Common errors can include:
AssertionErrorJSONErrorETIMEDOUT
2. Open the HTML Report
If you configured the HTML reporter, open the archived report from the CI job.
It can provide useful information about:
- Requests
- Headers
- Request bodies
- Responses
- Assertions
- Failed test steps
3. Check the Environment
Many "works on my machine" failures are caused by environment differences.
Check:
- Base URL
- Environment variables
- Authentication credentials
- Test data
- Environment files
- Expired tokens
- Missing CI secrets
4. Reproduce the Failure Locally
Run the same Newman command locally using the same collection and environment.
For additional request and response information, you can use:
newman run shop-api.postman_collection.json \
-e qa.postman_environment.json \
--verbose
5. Add Targeted Logging
Use console.log() when debugging Postman scripts.
console.log("Response status:", pm.response.code);
console.log("Response body:", pm.response.text());
The output appears in Newman's CLI output and can also be seen in the Jenkins console log.
Postman Console
When debugging locally in Postman, the Postman Console provides additional information.
Open:
View → Show Postman Console
It can show information about:
- Resolved request URLs
- Headers
- Request bodies
- Responses
- Script logs
Error Handling in Scripts — What Actually Happens
A popular approach is to wrap script logic in try/catch and simply log the error.
However, if the error is caught and never converted into a failed test, the CI run can appear successful.
For example:
❌ Catching and Only Logging the Error
try {
const body = pm.response.json();
pm.expect(body.data).to.exist;
} catch (e) {
console.log('Script error:', e.message);
}
If the JSON parsing fails, the error is logged, but the error is caught and not reported as a failed test.
✅ Put the Validation Inside pm.test
pm.test('response is JSON', () => {
pm.response.to.be.json;
});
pm.test('has data', () => {
const body = pm.response.json();
pm.expect(body).to.have.property('data');
});
This gives Newman explicit tests to execute and report.
The important distinction is that pm.test() records the validation as a test. If an exception occurs inside the test callback, Newman can report that test as failed.
If you do need to use try/catch, don't simply swallow the exception. Re-throw it or explicitly fail the test.
For example:
try {
const body = pm.response.json();
pm.expect(body).to.have.property('data');
} catch (e) {
console.log('Script error:', e.message);
pm.expect.fail(e.message);
}
This keeps the failure visible to the CI pipeline.
Stopping a Run Early
Sometimes there is no reason to continue executing the remaining requests after a critical request fails.
For example, if the login request fails and no authentication token is available, later authenticated requests may be meaningless.
if (pm.response.code !== 200) {
pm.execution.setNextRequest(null);
}
pm.execution.setNextRequest() controls the order of requests during a collection run.
Older collections may use:
postman.setNextRequest(null);
For stopping execution based on the first failed assertion from the command line, use:
newman run collection.json --bail
The two mechanisms serve different purposes:
pm.execution.setNextRequest(null)controls the collection's request flow.--bailtells Newman to stop after a failure.
Secrets in CI
Never commit passwords, API tokens or private credentials directly into Postman environment files stored in Git.
Instead:
- Store passwords, tokens and API keys in the CI credential store.
- Use Jenkins Credentials for Jenkins pipelines.
- Use GitHub Secrets for GitHub Actions.
- Inject secrets using
--env-var. - Keep secrets out of committed environment files.
- Avoid printing credentials with
console.log().
For more information about variables and scopes, see Postman Environments & Variables.
From Real Projects
My API testing experience covers CRUD operations, HTTP methods, JSON path, and validating JSON and XML data. On Testsigma, a platform that itself automates API tests, understanding requests, responses and status codes was part of understanding the product. Whatever tool you use, validate the status code, the response structure and the values — not just that the call returned something. Make a failed API test fail the build, and publish the report every time.
FAQs
What is Newman?
Newman is Postman's command-line collection runner. It allows Postman collections to run from terminals and CI/CD pipelines without opening the Postman application.
How does a failed API test fail the Jenkins build?
Newman exits with a non-zero code when an assertion fails. Jenkins detects the non-zero exit code and marks the pipeline step as failed.
Publishing the JUnit XML report adds structured failure information and allows Jenkins to display test results and trends.
How do you pass secrets to Newman in CI?
Store the secret in the CI credential system and inject it at runtime.
For example:
--env-var "name=value"
Do not commit passwords, tokens or API keys to Git.
How do you debug Postman scripts?
Use console.log() and the Postman Console when debugging locally.
For CI failures, examine:
- Newman failure output
- Jenkins console logs
- HTML reports
- JUnit results
- Environment configuration
You can then reproduce the same command locally with --verbose.
Should I wrap scripts in try/catch?
Usually, validation logic should be placed inside pm.test() so failures are reported as test failures.
A try/catch block that only logs the exception can hide a failure. If you use try/catch, make sure the error is explicitly re-thrown or converted into a failed assertion.
How do you stop a collection run?
You can stop the collection from a script with:
pm.execution.setNextRequest(null);
Alternatively, use Newman:
newman run collection.json --bail
Related
- Postman Scripting & Assertions
- Postman Cheat Sheet
- The Complete API Testing Tutorial
- Postman Newman CI/CD Practice
- The Complete Jenkins Tutorial
- API Testing Scenario Lab
- Postman Environments & Variables
📚 Official documentation: Postman Learning Center · MDN: HTTP