OKEx for Android
283.16MB · 2025-09-16
持续集成(CI)是一种频繁合并代码+自动验证的开发实践,核心目标是“让代码变更的风险最小化”。对于FastAPI这样的Web框架,CI的价值在于:用自动化替代手动操作,确保每一次代码变更都不会破坏接口功能、模型验证或代码风格。
FastAPI的设计依赖两个关键组件:pydantic
(数据验证)和路由
(接口逻辑)。CI需要自动化验证以下内容:
pytest
测试/items/
等接口是否返回预期结果(如无效name
是否被拒绝);pydantic
模型的约束(如min_length=3
、gt=0
)是否生效;flake8
检查代码风格,避免“一人一种写法”;Git Hook是Git在特定事件(如提交、推送)时自动运行的脚本,相当于“本地的门禁系统”。最常用的两个钩子是:
git commit
前运行,拦截“脏代码”(如测试失败、风格错误);git push
前运行,拦截“未通过集成测试的代码”。对于FastAPI开发,pre-commit
是最有效的本地质量保障——它能在你提交代码前快速反馈问题,避免将错误推送到远程仓库。
手动编写Git Hook脚本容易出错,推荐用pre-commit工具(Python库)简化配置:
pip install pre-commit==3.6.0 # 最新版本可通过pre-commit官网查询
在项目根目录创建该文件,定义要运行的“检查项”:
repos:
# 基础代码风格检查
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace # 去除行尾空格
- id: end-of-file-fixer # 确保文件以换行结尾
# Python代码风格检查
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
args: ["--max-line-length=120"] # 调整行宽限制
# 自动运行pytest测试
- repo: local
hooks:
- id: pytest
name: Run API Tests
entry: pytest # 运行pytest
language: system # 使用本地Python环境
types: [python] # 只检查Python文件
pass_filenames: false # 不传递文件名(运行所有测试)
always_run: true # 强制运行(即使无文件修改)
pre-commit install # 将钩子安装到Git
pre-commit run --all-files # 测试所有文件是否符合要求
假设你的FastAPI应用有一个Item
模型(用pydantic
定义):
# main.py
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str = Field(..., min_length=3, description="商品名称,至少3个字符")
price: float = Field(..., gt=0, description="商品价格,必须大于0")
@app.post("/items/")
def create_item(item: Item):
return {"message": f"创建商品 {item.name},价格 {item.price}"}
测试用例test_main.py
验证接口的合法性:
# test_main.py
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_create_item_valid():
"""测试合法输入"""
response = client.post("/items/", json={"name": "Apple", "price": 1.99})
assert response.status_code == 200
assert response.json() == {"message": "创建商品 Apple,价格 1.99"}
def test_create_item_invalid_name():
"""测试名称过短"""
response = client.post("/items/", json={"name": "Ap", "price": 1.99})
assert response.status_code == 422 # 验证错误
当你尝试提交名称过短的代码时,pre-commit
会自动运行pytest
,并阻止提交:
Run API Tests........................................................Failed
- hook id: pytest
- exit code: 1
============================= test session starts ==============================
collected 2 items
test_main.py .F [100%]
=================================== FAILURES ===================================
___________________________ test_create_item_invalid_name ___________________________
client = <starlette.testclient.TestClient object at 0x104f8d0d0>
def test_create_item_invalid_name():
response = client.post("/items/", json={"name": "Ap", "price": 1.99})
> assert response.status_code == 422
E assert 200 == 422 # 错误:接口意外返回了200(代码逻辑有问题)
test_main.py:15: AssertionError
============================== 1 failed, 1 passed in 0.12s ===============================
此时你需要修复代码逻辑(如确保Item
模型的min_length
生效),再重新提交。
推荐使用GitHub Actions(与GitHub仓库无缝集成),它能自动处理“代码推送→运行测试→构建镜像”的全流程。
在项目根目录创建.github/workflows/ci.yml
,定义流水线的“触发条件”和“步骤”:
name: FastAPI CI/CD # 流水线名称
# 触发条件:push到main分支或提交PR到main分支
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
# 第一个任务:运行测试
test:
runs-on: ubuntu-latest # 使用Ubuntu环境
steps:
- name: 拉取代码
uses: actions/checkout@v4 # 官方Action,拉取仓库代码
- name: 配置Python环境
uses: actions/setup-python@v5
with:
python-version: '3.11' # 与本地开发环境一致
- name: 安装依赖
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt # 安装requirements.txt中的依赖
- name: 运行pytest测试
run: pytest # 执行测试用例
# 第二个任务:构建Docker镜像(依赖test任务成功)
build:
needs: test # 只有test任务成功,才会运行build
runs-on: ubuntu-latest
steps:
- name: 拉取代码
uses: actions/checkout@v4
- name: 构建Docker镜像
run: docker build -t my-fastapi-app:${{ github.sha }} . # 用commit ID作为标签
当你执行git push origin main
时,GitHub Actions会自动:
pytest
,验证接口和模型;my-fastapi-project/
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions配置
├── .pre-commit-config.yaml # pre-commit配置
├── main.py # FastAPI应用
├── test_main.py # 测试用例
└── requirements.txt # 依赖清单
fastapi==0.110.0
uvicorn==0.27.0
pytest==7.4.4
requests==2.31.0
flake8==7.0.0
pre-commit==3.6.0
main.py
(如添加新接口);git commit -m "add item endpoint"
,pre-commit
自动运行pytest
和flake8
;git push origin main
,GitHub Actions触发CI流水线;在FastAPI项目中,为什么推荐同时使用Git Hook和CI流水线进行测试验证?
Git Hook是本地的快速反馈机制——能在代码提交前拦截小错误(如测试失败、代码风格),避免将无效代码推送到远程,减少CI的无效运行;而CI流水线是全局的统一验证机制——确保所有代码在一致的环境(如Ubuntu+Python3.11)中通过测试,避免本地环境与生产环境的差异(如Python版本不同导致的问题)。两者结合能最大化代码质量的保障效率:本地解决小问题,全局解决大问题。
pre-commit
工具,重新运行pre-commit install
(工具会自动设置权限);如果手动编写钩子,执行chmod +x .git/hooks/pre-commit
。pytest
运行失败(如接口返回状态码不符合预期、模型验证不通过)。test_create_item_invalid_name
的断言错误),修复代码逻辑(如确保Item
模型的min_length
生效),再重新提交。requirements.txt
未包含所有依赖(如缺少fastapi
或pytest
)。pip freeze > requirements.txt
,更新依赖清单,再重新推送代码。setup-python@v5
指定Python3.11),或使用python-dotenv
加载环境变量(如.env
文件中的DEBUG=True
)。FastAPI的高级特性(如pydantic模型、依赖注入)让开发更高效,但也需要自动化工具保障质量。Git Hook和CI流水线的结合,能让你在“快速开发”和“代码质量”之间找到平衡——本地用Git Hook快速反馈,云端用CI统一验证,最终实现“放心提交,安心上线”。
283.16MB · 2025-09-16
286.59MB · 2025-09-16
286.72MB · 2025-09-16