動態

詳情 返回 返回

FastAPI的CI流水線怎麼自動測端點,還能讓Allure報告美到犯規? - 動態 詳情


url: /posts/eed6cd8985d9be0a4b092a7da38b3e0c/
title: FastAPI的CI流水線怎麼自動測端點,還能讓Allure報告美到犯規?
date: 2025-09-16T01:32:40+08:00
lastmod: 2025-09-16T01:32:40+08:00
author: cmdragon

summary:
持續集成(CI)是一種軟件開發實踐,開發人員頻繁提交代碼,CI工具自動觸發構建和測試流程,以儘早發現錯誤。FastAPI項目通過CI保證類型安全、避免端點失效和一致性驗證。GitHub Actions是常用的CI工具,通過Workflow、Job和Step定義CI流程。FastAPI的CI流水線包括代碼拉取、Python環境設置、依賴安裝、測試和Docker鏡像構建。Allure測試報告框架生成可視化報告,支持結構化展示和跨平台兼容,與FastAPI的Pytest測試結合,通過Allure裝飾器標記測試用例,生成並查看報告。

categories:

  • fastapi

tags:

  • FastAPI
  • 持續集成
  • GitHub Actions
  • CI流水線
  • Pytest
  • Allure
  • 測試報告

<img src="https://api2.cmdragon.cn/upload/cmder/20250304_012821924.jpg" title="cmdragon_cn.png" alt="cmdragon_cn.png"/>

掃描二維碼關注或者微信搜一搜:編程智域 前端至全棧交流與成長

發現1000+提升效率與開發的AI工具和實用程序:https://tools.cmdragon.cn/

FastAPI與持續集成流水線構建

1.1 什麼是持續集成(CI)?

持續集成(Continuous Integration,簡稱CI)是一種軟件開發實踐:開發人員頻繁將代碼提交到共享倉庫(如GitHub的main分支),CI工具自動觸發構建、測試流程,儘早發現代碼中的錯誤。其核心目標是“快速反饋”——避免代碼集成時出現大規模衝突,或因單個提交破壞整個項目的功能。

對於FastAPI項目而言,CI的價值在於:

  • 保證類型安全:FastAPI依賴Pydantic模型做請求驗證,CI能自動檢查提交的代碼是否違反類型約束;
  • 避免端點失效:自動測試FastAPI的API端點(如GET /items/POST /users/),確保接口功能正常;
  • 一致性驗證:確保代碼在不同環境(開發、測試、生產)中的行為一致。

1.2 選擇CI工具:GitHub Actions為例

目前主流的CI工具包括GitHub Actions、GitLab CI、Jenkins等。本文以GitHub Actions為例(因多數FastAPI項目託管在GitHub,配置簡單且免費)。

GitHub Actions的核心概念:

  • Workflow(工作流):定義CI的觸發條件和執行步驟,存儲在項目根目錄的.github/workflows/文件夾中;
  • Job(任務):一個Workflow可包含多個Job,如“構建代碼”“運行測試”“推送鏡像”;
  • Step(步驟):Job的具體執行單元,如“拉取代碼”“安裝依賴”。

1.3 編寫FastAPI項目的CI流水線配置

以下是一個完整的FastAPI CI工作流文件.github/workflows/ci.yml),涵蓋“代碼拉取→依賴安裝→測試→構建Docker鏡像”:

name: FastAPI CI  # 工作流名稱
on:  # 觸發條件:Push到main分支或PR到main分支
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:  # 定義一個名為build-and-test的Job
    runs-on: ubuntu-latest  # 運行在Ubuntu最新版本的虛擬環境中
    steps:
      # 步驟1:拉取項目代碼(必須第一步,否則後續步驟無代碼可操作)
      - name: Checkout code
        uses: actions/checkout@v4  # 使用官方的checkout動作,拉取代碼到虛擬環境

      # 步驟2:設置Python環境(匹配項目的Python版本)
      - name: Set up Python 3.11
        uses: actions/setup-python@v5  # 官方的Python環境配置動作
        with:
          python-version: "3.11"  # 指定Python版本(需與項目依賴一致)

      # 步驟3:安裝項目依賴(使用requirements.txt)
      - name: Install dependencies
        run: |  # 運行Shell命令
          python -m pip install --upgrade pip  # 升級pip到最新版
          pip install -r requirements.txt  # 安裝requirements.txt中的依賴

      # 步驟4:運行Pytest測試(生成JUnit格式的測試報告)
      - name: Run tests with Pytest
        run: pytest --junitxml=test-results.xml  # 運行測試並生成JUnit報告(方便後續查看)

      # 步驟5:構建Docker鏡像(可選,若項目用Docker部署)
      - name: Build Docker image
        run: docker build -t my-fastapi-app:${{ github.sha }} .  # 構建鏡像,標籤用Git提交的SHA值(唯一標識)

配置説明

  • on字段:觸發CI的場景——當代碼推送到main分支,或有PR合併到main時,自動運行;
  • runs-on: ubuntu-latest:使用GitHub提供的Ubuntu虛擬環境,無需自己搭建服務器;
  • --junitxml=test-results.xml:生成JUnit格式的測試報告,方便GitHub Actions展示測試結果;
  • ${{ github.sha }}:GitHub的內置變量,代表當前提交的SHA哈希值,用於標記Docker鏡像版本(避免重複)。

1.4 流水線的關鍵步驟解析

  1. 拉取代碼(Checkout)
    使用actions/checkout@v4動作,將GitHub倉庫的代碼複製到CI的虛擬環境中,是所有CI工作流的基礎。
  2. 設置Python環境
    FastAPI依賴特定版本的Python(如3.9+),actions/setup-python@v5會自動安裝指定版本的Python,並配置pip等工具。若不設置,虛擬環境的Python版本可能與項目不兼容(如默認Python 3.8,而項目用Python 3.11),導致依賴安裝失敗。
  3. 安裝依賴
    通過pip install -r requirements.txt安裝項目所有依賴(包括FastAPI、Pydantic、Uvicorn等)。requirements.txt需包含項目的所有第三方庫及其版本(可通過pip freeze > requirements.txt生成)。
  4. 運行測試
    使用pytest運行測試用例(測試文件需以test_開頭,如test_main.py)。--junitxml參數生成的報告可在GitHub Actions的“Tests”標籤中查看,方便快速定位失敗的測試用例。

Allure測試報告可視化分析

2.1 Allure是什麼?

Allure是一款開源的測試報告框架,能生成美觀、互動的可視化報告(支持圖表、篩選、歷史對比)。與傳統的JUnit報告相比,Allure的優勢:

  • 結構化展示:按“功能模塊→用户故事→測試用例”分層,清晰呈現測試覆蓋範圍;
  • 豐富的元數據:支持標記測試用例的“優先級”“標籤”“附件”(如接口請求日誌);
  • 跨平台兼容:支持Python、Java、JavaScript等多語言,完美適配FastAPI的Pytest測試。

2.2 FastAPI與Allure的結合方式

FastAPI的測試通常使用pytestfastapi.TestClient(模擬HTTP請求),而Allure通過pytest插件allure-pytest)集成到測試流程中。具體步驟:

  1. 安裝Allure CLI和allure-pytest插件;
  2. 用Allure裝飾器標記測試用例(如@allure.feature“功能模塊”、@allure.story“用户故事”);
  3. 運行測試生成Allure結果文件;
  4. 啓動Allure服務查看可視化報告。

2.3 配置Allure環境

2.3.1 本地開發環境配置
  1. 安裝Java:Allure基於Java開發,需安裝JRE 8+(如OpenJDK 11):

    • Ubuntu:sudo apt install openjdk-11-jre
    • Mac:brew install openjdk@11
    • Windows:下載OpenJDK安裝包(https://adoptium.net/)。
  2. 安裝Allure CLI
    從Allure官網下載最新版本的CLI(https://github.com/allure-framework/allure2/releases),解壓後將bin目錄添加到系統PATH(如export PATH=$PATH:/path/to/allure-2.24.0/bin)。
  3. 安裝pytest插件

    pip install allure-pytest==2.13.2  # 最新版本(2024年3月)
2.3.2 CI環境配置(GitHub Actions)

在CI中安裝Allure需添加以下步驟(修改.github/workflows/ci.yml):

# 在“安裝依賴”步驟後添加:
- name: Set up Java 11
  uses: actions/setup-java@v4
  with:
    java-version: "11"
    distribution: "temurin"  # 使用Eclipse Temurin JDK(穩定且常用)

- name: Install Allure CLI
  run: |
    wget https://repo1.maven.org/maven2/io/qameta/allure/allure-commandline/2.24.0/allure-commandline-2.24.0.zip
    unzip allure-commandline-2.24.0.zip
    sudo mv allure-2.24.0 /opt/allure
    sudo ln -s /opt/allure/bin/allure /usr/bin/allure  # 添加到系統PATH

- name: Run tests with Allure
  run: pytest --alluredir=allure-results  # 生成Allure結果文件(存儲在allure-results目錄)

- name: Upload Allure results
  uses: actions/upload-artifact@v4  # 將結果文件上傳為GitHub artifact
  with:
    name: allure-results
    path: allure-results
    retention-days: 7  # 結果文件保留7天

2.4 編寫帶Allure標記的測試用例

以下是FastAPI的Allure測試用例示例test_main.py),覆蓋GET /POST /items/端點:

from fastapi.testclient import TestClient
from main import app  # 導入FastAPI應用實例
import allure

# 初始化TestClient(模擬HTTP客户端,用於測試FastAPI端點)
client = TestClient(app)

# 定義Item模型(與main.py中的模型一致,確保測試數據符合約束)
class Item:
    name: str
    price: float
    description: str | None = None

@allure.feature("Root Endpoint")  # 功能模塊:根路徑端點
@allure.story("Get Root Message")  # 用户故事:獲取根路徑的歡迎信息
@allure.title("Test root endpoint returns 200 OK")  # 測試用例標題
@allure.severity(allure.severity_level.CRITICAL)  # 優先級: critical(核心功能)
def test_read_root():
    # 發送GET請求到根路徑
    response = client.get("/")
    # 斷言狀態碼為200
    assert response.status_code == 200
    # 斷言響應內容符合預期
    assert response.json() == {"message": "Hello FastAPI"}

@allure.feature("Item Management")  # 功能模塊:商品管理
@allure.story("Create New Item")  # 用户故事:創建新商品
@allure.title("Test create item with valid data")  # 測試用例標題
@allure.severity(allure.severity_level.NORMAL)  # 優先級:normal(普通功能)
def test_create_item_valid_data():
    # 構造符合Pydantic約束的請求數據(price>0)
    item_data = {
        "name": "iPhone 15",
        "price": 9999.99,
        "description": "A new smartphone"
    }
    # 發送POST請求到/items/端點(JSON格式)
    response = client.post("/items/", json=item_data)
    # 斷言狀態碼為200
    assert response.status_code == 200
    # 斷言響應內容包含提交的數據(假設id自增)
    assert response.json() == {"id": 1, **item_data}

@allure.feature("Item Management")
@allure.story("Create New Item")
@allure.title("Test create item with invalid price")  # 測試用例標題:無效價格(price≤0)
@allure.severity(allure.severity_level.MINOR)  # 優先級:minor(次要功能)
def test_create_item_invalid_price():
    # 構造無效數據(price=0,違反Pydantic的gt=0約束)
    item_data = {
        "name": "Fake Phone",
        "price": 0,
        "description": "Invalid price"
    }
    # 發送POST請求
    response = client.post("/items/", json=item_data)
    # 斷言狀態碼為422(驗證錯誤)
    assert response.status_code == 422

2.5 生成與查看Allure報告

  1. 本地環境生成報告
    運行測試用例並生成Allure結果文件:

    pytest --alluredir=allure-results

    啓動Allure服務查看報告:

    allure serve allure-results

    瀏覽器會自動打開報告頁面(如http://localhost:5050),展示測試結果的統計信息(通過率、失敗率)和詳細的用例列表。

  2. CI環境查看報告
    在GitHub Actions的“Artifacts”標籤中下載allure-results壓縮包,解壓後在本地運行allure serve allure-results即可查看報告。

課後Quiz

問題1:

在FastAPI的CI流水線中,為什麼需要設置Python環境?請結合示例説明其作用。

答案解析:

CI的虛擬環境是“乾淨”的(默認沒有安裝任何Python庫),設置Python環境的作用是確保虛擬環境的Python版本與項目一致。例如:

  • 若項目用Python 3.11開發,而CI虛擬環境默認是Python 3.8,安裝FastAPI時會報錯(FastAPI 0.110.0要求Python ≥3.9);
  • 通過actions/setup-python@v5指定python-version: "3.11",可避免版本不兼容問題,確保依賴安裝和測試正常運行。

問題2:

Allure的@allure.feature@allure.story有什麼區別?請用FastAPI的“商品管理”模塊舉例説明。

答案解析:

  • @allure.feature:標記大的功能模塊(如“商品管理”“用户管理”);
  • @allure.story:標記功能模塊下的具體用户故事(如“創建商品”“刪除商品”“查詢商品列表”)。

舉例:

@allure.feature("商品管理")  # 功能模塊
@allure.story("創建商品")     # 用户故事
def test_create_item():
    # 測試用例代碼

常見報錯解決方案

報錯1:CI中運行pytest提示“ImportError: cannot import name 'app' from 'main'”

原因

  • 測試文件(如test_main.py)與main.py不在同一目錄,導致Python無法找到main模塊;
  • main.py中未定義app變量(app = FastAPI())。

解決

  1. 確保測試文件與main.py在同一目錄;
  2. 若測試文件在tests目錄下,需在conftest.py中添加以下代碼(將項目根目錄加入Python路徑):

    import sys
    sys.path.append(".")  # 項目根目錄(包含main.py的目錄)

預防
保持清晰的項目結構(如tests目錄存放測試文件,main.py在根目錄),並在pyproject.toml中配置Pytest的根目錄:

[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["."]

報錯2:Allure報告提示“Empty test suite”(無測試結果)

原因

  • 測試文件未以test_開頭(如main_test.py,Pytest默認不會識別);
  • 測試函數未以test_開頭(如create_item_test(),Pytest不會執行);
  • --alluredir參數指定的目錄錯誤(如allure-results拼寫錯誤)。

解決

  1. 修改測試文件/函數名稱,確保以test_開頭;
  2. 檢查pytest命令的--alluredir參數,確保目錄名稱正確(如allure-results)。

預防
遵循Pytest的命名規範(測試文件test_*.py、測試函數test_*),並在pyproject.toml中配置Pytest的測試文件匹配規則:

[tool.pytest.ini_options]
python_files = "test_*.py"
python_functions = "test_*"

報錯3:FastAPI測試提示“422 Unprocessable Entity”

原因
請求數據違反Pydantic模型的約束(如price字段小於等於0,或name字段為空)。

解決

  1. 檢查測試用例的請求數據,確保符合Pydantic模型的所有約束;
  2. 使用response.json()查看詳細的錯誤信息(如"msg": "Input should be greater than 0")。

示例
Item模型的price字段定義為price: float = Field(..., gt=0),則測試用例中的price必須大於0:

# 錯誤數據(price=0)
item_data = {"name": "Fake Phone", "price": 0}
# 正確數據(price=999.99)
item_data = {"name": "iPhone 15", "price": 999.99}

預防
在編寫測試用例前,仔細閲讀Pydantic模型的約束條件(如gtmin_lengthregex),確保測試數據符合要求。

餘下文章內容請點擊跳轉至 個人博客頁面 或者 掃碼關注或者微信搜一搜:編程智域 前端至全棧交流與成長,閲讀完整的文章:FastAPI的CI流水線怎麼自動測端點,還能讓Allure報告美到犯規?

<details>
<summary>往期文章歸檔</summary>

  • 如何用GitHub Actions為FastAPI項目打造自動化測試流水線? - cmdragon's Blog
  • 如何用Git Hook和CI流水線為FastAPI項目保駕護航? - cmdragon's Blog
  • FastAPI如何用契約測試確保API的「菜單」與「菜品」一致?
  • 為什麼TDD能讓你的FastAPI開發飛起來? - cmdragon's Blog
  • 如何用FastAPI玩轉多模塊測試與異步任務,讓代碼不再“鬧脾氣”? - cmdragon's Blog
  • 如何在FastAPI中玩轉“時光倒流”的數據庫事務回滾測試?
  • 如何在FastAPI中優雅地模擬多模塊集成測試? - cmdragon's Blog
  • 多環境配置切換機制能否讓開發與生產無縫銜接? - cmdragon's Blog
  • 如何在 FastAPI 中巧妙覆蓋依賴注入並攔截第三方服務調用? - cmdragon's Blog
  • 為什麼你的單元測試需要Mock數據庫才能飛起來? - cmdragon's Blog
  • 如何在FastAPI中巧妙隔離依賴項,讓單元測試不再頭疼? - cmdragon's Blog
  • 如何在FastAPI中巧妙隔離依賴項,讓單元測試不再頭疼? - cmdragon's Blog
  • 測試覆蓋率不夠高?這些技巧讓你的FastAPI測試無懈可擊! - cmdragon's Blog
  • 為什麼你的FastAPI測試覆蓋率總是低得讓人想哭? - cmdragon's Blog
  • 如何讓FastAPI測試不再成為你的噩夢? - cmdragon's Blog
  • FastAPI測試環境配置的秘訣,你真的掌握了嗎? - cmdragon's Blog
  • 全鏈路追蹤如何讓FastAPI微服務架構的每個請求都無所遁形? - cmdragon's Blog
  • 如何在API高併發中玩轉資源隔離與限流策略? - cmdragon's Blog
  • 任務分片執行模式如何讓你的FastAPI性能飆升? - cmdragon's Blog
  • 冷熱任務分離:是提升Web性能的終極秘籍還是技術噱頭? - cmdragon's Blog
  • 如何讓FastAPI在百萬級任務處理中依然遊刃有餘? - cmdragon's Blog
  • 如何讓FastAPI與消息隊列的聯姻既甜蜜又可靠? - cmdragon's Blog
  • 如何在FastAPI中巧妙實現延遲隊列,讓任務乖乖等待? - cmdragon's Blog
  • FastAPI的死信隊列處理機制:為何你的消息系統需要它? - cmdragon's Blog
  • 如何讓FastAPI任務系統在失敗時自動告警並自我修復? - cmdragon's Blog
  • 如何用Prometheus和FastAPI打造任務監控的“火眼金睛”? - cmdragon's Blog
  • 如何用APScheduler和FastAPI打造永不宕機的分佈式定時任務系統? - cmdragon's Blog
  • 如何在 FastAPI 中玩轉 APScheduler,讓任務定時自動執行? - cmdragon's Blog
  • 定時任務系統如何讓你的Web應用自動完成那些煩人的重複工作? - cmdragon's Blog
  • Celery任務監控的魔法背後藏着什麼秘密? - cmdragon's Blog
  • 如何讓Celery任務像VIP客户一樣享受優先待遇? - cmdragon's Blog
  • 如何讓你的FastAPI Celery Worker在壓力下優雅起舞? - cmdragon's Blog
  • FastAPI與Celery的完美邂逅,如何讓異步任務飛起來? - cmdragon's Blog
  • FastAPI消息持久化與ACK機制:如何確保你的任務永不迷路? - cmdragon's Blog
  • FastAPI的BackgroundTasks如何玩轉生產者-消費者模式? - cmdragon's Blog
  • BackgroundTasks 還是 RabbitMQ?你的異步任務到底該選誰? - cmdragon's Blog
  • BackgroundTasks與Celery:誰才是異步任務的終極贏家? - cmdragon's Blog

</details>

<details>
<summary>免費好用的熱門在線工具</summary>

  • 歌詞生成工具 - 應用商店 | By cmdragon
  • 網盤資源聚合搜索 - 應用商店 | By cmdragon
  • ASCII字符畫生成器 - 應用商店 | By cmdragon
  • JSON Web Tokens 工具 - 應用商店 | By cmdragon
  • Bcrypt 密碼工具 - 應用商店 | By cmdragon
  • GIF 合成器 - 應用商店 | By cmdragon
  • GIF 分解器 - 應用商店 | By cmdragon
  • 文本隱寫術 - 應用商店 | By cmdragon
  • CMDragon 在線工具 - 高級AI工具箱與開發者套件 | 免費好用的在線工具
  • 應用商店 - 發現1000+提升效率與開發的AI工具和實用程序 | 免費好用的在線工具
  • CMDragon 更新日誌 - 最新更新、功能與改進 | 免費好用的在線工具
  • 支持我們 - 成為贊助者 | 免費好用的在線工具
  • AI文本生成圖像 - 應用商店 | 免費好用的在線工具
  • 臨時郵箱 - 應用商店 | 免費好用的在線工具
  • 二維碼解析器 - 應用商店 | 免費好用的在線工具
  • 文本轉思維導圖 - 應用商店 | 免費好用的在線工具
  • 正則表達式可視化工具 - 應用商店 | 免費好用的在線工具
  • 文件隱寫工具 - 應用商店 | 免費好用的在線工具
  • IPTV 頻道探索器 - 應用商店 | 免費好用的在線工具
  • 快傳 - 應用商店 | 免費好用的在線工具
  • 隨機抽獎工具 - 應用商店 | 免費好用的在線工具
  • 動漫場景查找器 - 應用商店 | 免費好用的在線工具
  • 時間工具箱 - 應用商店 | 免費好用的在線工具
  • 網速測試 - 應用商店 | 免費好用的在線工具
  • AI 智能摳圖工具 - 應用商店 | 免費好用的在線工具
  • 背景替換工具 - 應用商店 | 免費好用的在線工具
  • 藝術二維碼生成器 - 應用商店 | 免費好用的在線工具
  • Open Graph 元標籤生成器 - 應用商店 | 免費好用的在線工具
  • 圖像對比工具 - 應用商店 | 免費好用的在線工具
  • 圖片壓縮專業版 - 應用商店 | 免費好用的在線工具
  • 密碼生成器 - 應用商店 | 免費好用的在線工具
  • SVG優化器 - 應用商店 | 免費好用的在線工具
  • 調色板生成器 - 應用商店 | 免費好用的在線工具
  • 在線節拍器 - 應用商店 | 免費好用的在線工具
  • IP歸屬地查詢 - 應用商店 | 免費好用的在線工具
  • CSS網格佈局生成器 - 應用商店 | 免費好用的在線工具
  • 郵箱驗證工具 - 應用商店 | 免費好用的在線工具
  • 書法練習字帖 - 應用商店 | 免費好用的在線工具
  • 金融計算器套件 - 應用商店 | 免費好用的在線工具
  • 中國親戚關係計算器 - 應用商店 | 免費好用的在線工具
  • Protocol Buffer 工具箱 - 應用商店 | 免費好用的在線工具
  • IP歸屬地查詢 - 應用商店 | 免費好用的在線工具
  • 圖片無損放大 - 應用商店 | 免費好用的在線工具
  • 文本比較工具 - 應用商店 | 免費好用的在線工具
  • IP批量查詢工具 - 應用商店 | 免費好用的在線工具
  • 域名查詢工具 - 應用商店 | 免費好用的在線工具
  • DNS工具箱 - 應用商店 | 免費好用的在線工具
  • 網站圖標生成器 - 應用商店 | 免費好用的在線工具
  • XML Sitemap

</details>

user avatar sevencoding 頭像 doge_king 頭像 xingguangshanshan 頭像
點贊 3 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.