软件测试接口测试从入门到精通:接口测试CI_CD集成

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
流程
代码提交
自动构建
自动测试
自动报告
实践
环境变量
秘密管理
失败通知

课后练习 📝

  1. 实践题:为你的项目配置GitHub Actions工作流,自动运行接口测试。

  2. 进阶题:配置Jenkins Pipeline,集成Allure报告。


21.7 下章预告

下一章我们将学习接口测试报告与监控!


"CI/CD让测试从'事后检查'变成'实时守护'。"

相关推荐
程序员三藏9 小时前
Web自动化测试详解
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
糖果店的幽灵14 小时前
软件测试接口测试从入门到精通:接口功能测试实战 - 从理论到实践
软件测试·功能测试·接口测试
糖果店的幽灵17 小时前
软件测试接口测试从入门到精通:Python接口自动化 - pytest测试框架
软件测试·python·功能测试·自动化·pytest·接口测试
程序员龙叔17 小时前
从 0 开始学习 AI 测试 - 从接口测试来教你如何用 AI 来生成自动化测试代码
自动化测试·软件测试·python·软件测试工程师·测试工具·性能测试·ai测试
糖果店的幽灵20 小时前
软件测试接口测试从入门到精通:Python接口自动化 - requests库
开发语言·软件测试·python·功能测试·自动化·接口测试
muddjsv21 小时前
从零吃透:软件测试全套核心理论体系深度解析
软件测试
糖果店的幽灵21 小时前
软件测试接口测试从入门到精通:接口参数化与数据驱动 - 一套用例,多种数据
软件测试·接口测试
平头老王1 天前
CI/CD流水线设计 — 第1章:常见误区
ci/cd·自动化·devops·持续部署·持续集成
糖果店的幽灵2 天前
软件测试接口测试从入门到精通:其他接口测试工具
软件测试·测试工具·接口测试·apifox·insomnia