21 接口测试 CI/CD 集成 - 自动化流水线
🎯 本章目标:理解CI/CD概念,掌握Jenkins和GitHub Actions集成接口测试的方法。
21.1 什么是CI/CD
生活中的类比
想象一个自动化餐厅:
传统餐厅:
厨师炒菜 → 服务员端菜 → 顾客品尝 → 发现问题 → 回厨房重做
自动化餐厅(CI/CD):
食材准备 → 自动烹饪 → 自动质检 → 自动上菜
发现问题立即报警,不会端到顾客面前
CI/CD定义
CI(Continuous Integration,持续集成) :频繁地将代码集成到主干,每次集成自动构建和测试。
CD(Continuous Delivery/Deployment,持续交付/部署):自动将验证通过的代码部署到生产环境。
#mermaid-svg-n7ctqU9mxuCoTeX2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-n7ctqU9mxuCoTeX2 .error-icon{fill:#552222;}#mermaid-svg-n7ctqU9mxuCoTeX2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-n7ctqU9mxuCoTeX2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .marker.cross{stroke:#333333;}#mermaid-svg-n7ctqU9mxuCoTeX2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-n7ctqU9mxuCoTeX2 p{margin:0;}#mermaid-svg-n7ctqU9mxuCoTeX2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .cluster-label text{fill:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .cluster-label span{color:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .cluster-label span p{background-color:transparent;}#mermaid-svg-n7ctqU9mxuCoTeX2 .label text,#mermaid-svg-n7ctqU9mxuCoTeX2 span{fill:#333;color:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .node rect,#mermaid-svg-n7ctqU9mxuCoTeX2 .node circle,#mermaid-svg-n7ctqU9mxuCoTeX2 .node ellipse,#mermaid-svg-n7ctqU9mxuCoTeX2 .node polygon,#mermaid-svg-n7ctqU9mxuCoTeX2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .rough-node .label text,#mermaid-svg-n7ctqU9mxuCoTeX2 .node .label text,#mermaid-svg-n7ctqU9mxuCoTeX2 .image-shape .label,#mermaid-svg-n7ctqU9mxuCoTeX2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-n7ctqU9mxuCoTeX2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .rough-node .label,#mermaid-svg-n7ctqU9mxuCoTeX2 .node .label,#mermaid-svg-n7ctqU9mxuCoTeX2 .image-shape .label,#mermaid-svg-n7ctqU9mxuCoTeX2 .icon-shape .label{text-align:center;}#mermaid-svg-n7ctqU9mxuCoTeX2 .node.clickable{cursor:pointer;}#mermaid-svg-n7ctqU9mxuCoTeX2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .arrowheadPath{fill:#333333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n7ctqU9mxuCoTeX2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-n7ctqU9mxuCoTeX2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n7ctqU9mxuCoTeX2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-n7ctqU9mxuCoTeX2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .cluster text{fill:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 .cluster span{color:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-n7ctqU9mxuCoTeX2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-n7ctqU9mxuCoTeX2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-n7ctqU9mxuCoTeX2 .icon-shape,#mermaid-svg-n7ctqU9mxuCoTeX2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n7ctqU9mxuCoTeX2 .icon-shape p,#mermaid-svg-n7ctqU9mxuCoTeX2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-n7ctqU9mxuCoTeX2 .icon-shape .label rect,#mermaid-svg-n7ctqU9mxuCoTeX2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n7ctqU9mxuCoTeX2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-n7ctqU9mxuCoTeX2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-n7ctqU9mxuCoTeX2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 代码提交
自动构建
单元测试
接口测试
部署到测试环境
UI测试
部署到生产环境
21.2 为什么接口测试要集成到CI/CD
好处
#mermaid-svg-8IgsBkJCoEwKQg8h{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8IgsBkJCoEwKQg8h .error-icon{fill:#552222;}#mermaid-svg-8IgsBkJCoEwKQg8h .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8IgsBkJCoEwKQg8h .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8IgsBkJCoEwKQg8h .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8IgsBkJCoEwKQg8h .marker.cross{stroke:#333333;}#mermaid-svg-8IgsBkJCoEwKQg8h svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8IgsBkJCoEwKQg8h p{margin:0;}#mermaid-svg-8IgsBkJCoEwKQg8h .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h .cluster-label text{fill:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h .cluster-label span{color:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h .cluster-label span p{background-color:transparent;}#mermaid-svg-8IgsBkJCoEwKQg8h .label text,#mermaid-svg-8IgsBkJCoEwKQg8h span{fill:#333;color:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h .node rect,#mermaid-svg-8IgsBkJCoEwKQg8h .node circle,#mermaid-svg-8IgsBkJCoEwKQg8h .node ellipse,#mermaid-svg-8IgsBkJCoEwKQg8h .node polygon,#mermaid-svg-8IgsBkJCoEwKQg8h .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8IgsBkJCoEwKQg8h .rough-node .label text,#mermaid-svg-8IgsBkJCoEwKQg8h .node .label text,#mermaid-svg-8IgsBkJCoEwKQg8h .image-shape .label,#mermaid-svg-8IgsBkJCoEwKQg8h .icon-shape .label{text-anchor:middle;}#mermaid-svg-8IgsBkJCoEwKQg8h .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8IgsBkJCoEwKQg8h .rough-node .label,#mermaid-svg-8IgsBkJCoEwKQg8h .node .label,#mermaid-svg-8IgsBkJCoEwKQg8h .image-shape .label,#mermaid-svg-8IgsBkJCoEwKQg8h .icon-shape .label{text-align:center;}#mermaid-svg-8IgsBkJCoEwKQg8h .node.clickable{cursor:pointer;}#mermaid-svg-8IgsBkJCoEwKQg8h .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8IgsBkJCoEwKQg8h .arrowheadPath{fill:#333333;}#mermaid-svg-8IgsBkJCoEwKQg8h .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8IgsBkJCoEwKQg8h .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8IgsBkJCoEwKQg8h .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8IgsBkJCoEwKQg8h .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8IgsBkJCoEwKQg8h .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8IgsBkJCoEwKQg8h .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8IgsBkJCoEwKQg8h .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8IgsBkJCoEwKQg8h .cluster text{fill:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h .cluster span{color:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8IgsBkJCoEwKQg8h .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8IgsBkJCoEwKQg8h rect.text{fill:none;stroke-width:0;}#mermaid-svg-8IgsBkJCoEwKQg8h .icon-shape,#mermaid-svg-8IgsBkJCoEwKQg8h .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8IgsBkJCoEwKQg8h .icon-shape p,#mermaid-svg-8IgsBkJCoEwKQg8h .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8IgsBkJCoEwKQg8h .icon-shape .label rect,#mermaid-svg-8IgsBkJCoEwKQg8h .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8IgsBkJCoEwKQg8h .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8IgsBkJCoEwKQg8h .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8IgsBkJCoEwKQg8h :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CI/CD集成好处
快速反馈
质量保证
减少人工
可追溯
提交后立即知道结果
每次提交都经过测试
自动执行无需人工
知道哪次提交引入问题
21.3 Jenkins集成
Jenkins简介
Jenkins 是最流行的开源CI/CD工具,支持丰富的插件生态。
安装Jenkins
bash
# Docker安装
docker run -d -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts
创建Pipeline
Jenkinsfile:
groovy
pipeline {
agent any
environment {
PYTHON_VERSION = '3.9'
}
stages {
stage('Checkout') {
steps {
git 'https://github.com/your-repo/api-tests.git'
}
}
stage('Install Dependencies') {
steps {
sh '''
python -m pip install --upgrade pip
pip install -r requirements.txt
'''
}
}
stage('Run API Tests') {
steps {
sh '''
pytest tests/ -v --html=reports/report.html --self-contained-html
'''
}
}
stage('Generate Report') {
steps {
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'reports',
reportFiles: 'report.html',
reportName: 'API Test Report'
])
}
}
}
post {
always {
junit 'reports/*.xml'
}
failure {
mail to: 'team@example.com',
subject: "API Tests Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
body: "Check console output at ${env.BUILD_URL}"
}
}
}
21.4 GitHub Actions集成
GitHub Actions简介
GitHub Actions 是GitHub内置的CI/CD服务,直接在代码仓库中配置工作流。
配置工作流
.github/workflows/api-tests.yml:
yaml
name: API Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run API tests
run: |
pytest tests/ -v --html=reports/report.html --self-contained-html
env:
BASE_URL: ${{ secrets.BASE_URL }}
TEST_USERNAME: ${{ secrets.TEST_USERNAME }}
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
- name: Upload test report
uses: actions/upload-artifact@v3
if: always()
with:
name: test-report
path: reports/
21.5 测试环境管理
环境配置
python
# config/settings.py
import os
class Settings:
ENV = os.getenv("ENV", "test")
if ENV == "dev":
BASE_URL = "https://api-dev.example.com"
elif ENV == "test":
BASE_URL = "https://api-test.example.com"
elif ENV == "prod":
BASE_URL = "https://api.example.com"
TIMEOUT = int(os.getenv("TIMEOUT", "10"))
settings = Settings()
21.6 本章小结
CI/CD集成核心
#mermaid-svg-AXtNMlR0fxwY2r8G{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AXtNMlR0fxwY2r8G .error-icon{fill:#552222;}#mermaid-svg-AXtNMlR0fxwY2r8G .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AXtNMlR0fxwY2r8G .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AXtNMlR0fxwY2r8G .marker.cross{stroke:#333333;}#mermaid-svg-AXtNMlR0fxwY2r8G svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AXtNMlR0fxwY2r8G p{margin:0;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge{stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 text{fill:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth--1{stroke-width:17;}#mermaid-svg-AXtNMlR0fxwY2r8G .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-0{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-0{stroke-width:14;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-1{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-1{stroke-width:11;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 text{fill:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-2{stroke-width:8;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-3{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-3{stroke-width:5;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-4{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-4{stroke-width:2;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-5{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-5{stroke-width:-1;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-6{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-6{stroke-width:-4;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-7{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-7{stroke-width:-7;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-8{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-8{stroke-width:-10;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-9{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-9{stroke-width:-13;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 polygon,#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 text{fill:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .node-icon-10{font-size:40px;color:black;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .edge-depth-10{stroke-width:-16;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled circle,#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:lightgray;}#mermaid-svg-AXtNMlR0fxwY2r8G .disabled text{fill:#efefef;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-root rect,#mermaid-svg-AXtNMlR0fxwY2r8G .section-root path,#mermaid-svg-AXtNMlR0fxwY2r8G .section-root circle,#mermaid-svg-AXtNMlR0fxwY2r8G .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-AXtNMlR0fxwY2r8G .section-root text{fill:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-root span{color:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .section-2 span{color:#ffffff;}#mermaid-svg-AXtNMlR0fxwY2r8G .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-AXtNMlR0fxwY2r8G .edge{fill:none;}#mermaid-svg-AXtNMlR0fxwY2r8G .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-AXtNMlR0fxwY2r8G :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CI/CD
工具
Jenkins
GitHub Actions
GitLab CI
流程
代码提交
自动构建
自动测试
自动报告
实践
环境变量
秘密管理
失败通知
课后练习 📝
-
实践题:为你的项目配置GitHub Actions工作流,自动运行接口测试。
-
进阶题:配置Jenkins Pipeline,集成Allure报告。
21.7 下章预告
下一章我们将学习接口测试报告与监控!
"CI/CD让测试从'事后检查'变成'实时守护'。"