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 流水線的關鍵步驟解析
- 拉取代碼(Checkout):
使用actions/checkout@v4動作,將GitHub倉庫的代碼複製到CI的虛擬環境中,是所有CI工作流的基礎。 - 設置Python環境:
FastAPI依賴特定版本的Python(如3.9+),actions/setup-python@v5會自動安裝指定版本的Python,並配置pip等工具。若不設置,虛擬環境的Python版本可能與項目不兼容(如默認Python 3.8,而項目用Python 3.11),導致依賴安裝失敗。 - 安裝依賴:
通過pip install -r requirements.txt安裝項目所有依賴(包括FastAPI、Pydantic、Uvicorn等)。requirements.txt需包含項目的所有第三方庫及其版本(可通過pip freeze > requirements.txt生成)。 - 運行測試:
使用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的測試通常使用pytest和fastapi.TestClient(模擬HTTP請求),而Allure通過pytest插件(allure-pytest)集成到測試流程中。具體步驟:
- 安裝Allure CLI和
allure-pytest插件; - 用Allure裝飾器標記測試用例(如
@allure.feature“功能模塊”、@allure.story“用户故事”); - 運行測試生成Allure結果文件;
- 啓動Allure服務查看可視化報告。
2.3 配置Allure環境
2.3.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/)。
- Ubuntu:
- 安裝Allure CLI:
從Allure官網下載最新版本的CLI(https://github.com/allure-framework/allure2/releases),解壓後將bin目錄添加到系統PATH(如export PATH=$PATH:/path/to/allure-2.24.0/bin)。 -
安裝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報告
-
本地環境生成報告:
運行測試用例並生成Allure結果文件:pytest --alluredir=allure-results啓動Allure服務查看報告:
allure serve allure-results瀏覽器會自動打開報告頁面(如
http://localhost:5050),展示測試結果的統計信息(通過率、失敗率)和詳細的用例列表。 - 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())。
解決:
- 確保測試文件與
main.py在同一目錄; -
若測試文件在
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拼寫錯誤)。
解決:
- 修改測試文件/函數名稱,確保以
test_開頭; - 檢查
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字段為空)。
解決:
- 檢查測試用例的請求數據,確保符合Pydantic模型的所有約束;
- 使用
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模型的約束條件(如gt、min_length、regex),確保測試數據符合要求。
餘下文章內容請點擊跳轉至 個人博客頁面 或者 掃碼關注或者微信搜一搜:編程智域 前端至全棧交流與成長,閲讀完整的文章: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>