Advanced
Chapter 20 · 13 min read
CI/CD Integration & Reporting
Integrate API tests into CI/CD pipelines (GitHub Actions, Jenkins), generate HTML/Allure reports, and set up automated test execution.
CI/CD Integration & Reporting
The final piece of a mature API testing strategy is automation. Your tests should run automatically on every code change, with clear reports that make failures actionable.
CI/CD Platforms
- GitHub Actions — Built-in to GitHub, YAML-based, free for public repos
- Jenkins — Self-hosted, highly customizable, plugin ecosystem
- GitLab CI — Integrated with GitLab, Docker-native
- Azure Pipelines — Microsoft ecosystem, multi-platform
Reporting
Good test reports show what passed, what failed, why it failed, and how long it took. Use Allure for rich interactive reports, JUnit XML for CI integration, or HTML reports for quick sharing.
Best Practices
Run API tests on every pull request, block merges on test failures, track test trends over time, and set up Slack/email alerts for failures in production monitoring.
.github/workflows/api-tests.yml
# GitHub Actions workflow for JS API tests
name: API Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 6 * * *' # Daily at 6 AM UTC
jobs:
api-tests:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Run API tests
run: npm test -- --reporter mocha-multi-reporters --reporter-options configFile=reporter-config.json
env:
TEST_ENV: staging
API_TOKEN: ${{ secrets.API_TOKEN }}
- name: Upload test report
uses: actions/upload-artifact@v4
if: always()
with:
name: test-report-node${{ matrix.node-version }}
path: reports/
- name: Publish Test Results
uses: dorny/test-reporter@v1
if: always()
with:
name: API Test Results
path: reports/junit.xml
reporter: java-junit
reporter-config.json
{
"reporterEnabled": "spec, mocha-junit-reporter",
"mochaJunitReporterReporterOptions": {
"mochaFile": "reports/junit.xml",
"toConsole": true
}
}
Jenkinsfile
// Jenkinsfile for Java API tests
pipeline {
agent any
tools {
maven 'Maven-3.9'
jdk 'JDK-17'
}
environment {
API_TOKEN = credentials('api-token')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run API Tests') {
steps {
sh '''
mvn clean test \
-Denv=staging \
-Dapi.token=${API_TOKEN}
'''
}
}
stage('Generate Reports') {
steps {
// Allure report
allure includeProperties: false,
results: [[path: 'target/allure-results']]
// JUnit results
junit 'target/surefire-reports/*.xml'
}
}
}
post {
failure {
// Slack notification on failure
slackSend color: 'danger',
message: "API Tests FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
}
always {
archiveArtifacts artifacts: 'target/surefire-reports/**',
allowEmptyArchive: true
}
}
}
pom-reporting.xml
<!-- Add to pom.xml for Allure reporting -->
<dependencies>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>2.25.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.12.0</version>
<configuration>
<reportVersion>2.25.0</reportVersion>
</configuration>
</plugin>
</plugins>
</build>
<!-- Run: mvn clean test allure:report -->
<!-- View: mvn allure:serve -->
.github/workflows/api-tests.yml
# GitHub Actions workflow for Python API tests
name: API Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 6 * * *'
jobs:
api-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.12']
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run API tests with HTML report
run: |
pytest tests/ \
--html=reports/report.html \
--self-contained-html \
--junitxml=reports/junit.xml \
-v
env:
TEST_ENV: staging
API_TOKEN: ${{ secrets.API_TOKEN }}
- name: Upload test report
uses: actions/upload-artifact@v4
if: always()
with:
name: test-report-py${{ matrix.python-version }}
path: reports/
- name: Publish Test Results
uses: dorny/test-reporter@v1
if: always()
with:
name: API Test Results (Python ${{ matrix.python-version }})
path: reports/junit.xml
reporter: java-junit
pytest.ini
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts =
-v
--tb=short
--strict-markers
markers =
smoke: Quick smoke tests
regression: Full regression suite
performance: Performance tests
# Run smoke only: pytest -m smoke
# Run all except perf: pytest -m "not performance"
# Generate HTML: pytest --html=reports/report.html
API Testing
Advanced
CI/CD Integration & Reporting
Written by PV
© 2026 All Rights Reserved