backend-bugfix
SKILL.md
Backend Bugfix Workflow Skill
本 skill 提供后端测试 bugfix 的完整工作流知识,包括错误分类体系、置信度评分系统和 TDD 最佳实践。
错误分类体系
后端测试失败主要分为以下类型(按频率排序):
1. 数据库错误(30%)
症状:数据库连接失败、查询错误、事务问题
识别特征:
IntegrityError、OperationalErrorsqlalchemy.exc.*异常UNIQUE constraint failed- 事务未提交或未回滚
解决策略:正确处理事务边界
# Before - 事务未正确处理
def create_user(db: Session, user: UserCreate):
db_user = User(**user.dict())
db.add(db_user)
db.commit() # 失败时无回滚
return db_user
# After - 使用 try/except 确保事务安全
def create_user(db: Session, user: UserCreate):
try:
db_user = User(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
except IntegrityError:
db.rollback()
raise HTTPException(status_code=409, detail="User already exists")
2. 验证错误(25%)
症状:输入验证失败、Schema 不匹配
识别特征:
ValidationErrorpydantic.error_wrappers422 Unprocessable Entityfield required错误
解决策略:完善 Pydantic Schema
# Before - 缺少验证
class UserCreate(BaseModel):
email: str # 没有格式验证
# After - 使用 Pydantic 验证器
class UserCreate(BaseModel):
email: EmailStr
@field_validator('email')
@classmethod
def email_must_be_valid(cls, v):
if not v or '@' not in v:
raise ValueError('Invalid email format')
return v.lower()
3. API 错误(20%)
症状:端点返回错误状态码、路由不匹配
识别特征:
HTTPException404 Not Found、405 Method Not Allowed- 响应格式不符合预期
解决策略:检查路由定义和请求方法
# 确保端点定义正确
@router.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(User).filter(User.id == user_id).first()
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
4. 认证错误(10%)
症状:认证失败、权限不足
识别特征:
401 Unauthorized403 Forbidden- Token 相关错误
credentials验证失败
解决策略:检查认证流程和 Token 处理
# 确保 Token 验证正确
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
raise credentials_exception
except JWTError:
raise credentials_exception
return user_id
5. 异步错误(8%)
症状:异步操作超时、并发问题
识别特征:
TimeoutErrorCancelledErrorasyncio相关异常- 缺少
await关键字
解决策略:正确使用 async/await
# Before - 忘记 await
async def get_data():
result = fetch_from_external_api() # 缺少 await
return result
# After - 正确等待异步操作
async def get_data():
result = await fetch_from_external_api()
return result
6. 配置错误(5%)
症状:配置加载失败、环境变量缺失
识别特征:
KeyErrorenvironment相关错误settings加载失败
解决策略:使用 Pydantic Settings 管理配置
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
secret_key: str
class Config:
env_file = ".env"
settings = Settings()
置信度评分系统
评分标准(0-100)
| 分数 | 级别 | 行为 |
|---|---|---|
| 80+ | 高 | 自动执行 |
| 60-79 | 中 | 标记验证后继续 |
| 40-59 | 低 | 暂停询问用户 |
| <40 | 不确定 | 停止收集信息 |
置信度计算
置信度 = 证据质量(40%) + 模式匹配(30%) + 上下文完整性(20%) + 可复现性(10%)
证据质量:
- 高:有完整堆栈、行号、可稳定复现
- 中:有错误信息但缺上下文
- 低:仅有模糊描述
模式匹配:
- 高:完全匹配已知错误模式
- 中:部分匹配
- 低:未知错误类型
上下文完整性:
- 高:测试代码 + 源代码 + 配置 + 数据库 Schema
- 中:只有测试或源代码
- 低:只有错误信息
可复现性:
- 高:每次运行都复现
- 中:偶发(可能与数据或并发相关)
- 低:环境相关
TDD 流程
RED Phase(写失败测试)
import pytest
from fastapi.testclient import TestClient
def test_create_user_duplicate_email(client: TestClient, db_session):
"""测试重复邮箱应返回 409"""
# 1. 设置前置条件
client.post("/api/users", json={"email": "test@example.com", "name": "User 1"})
# 2. 执行被测操作
response = client.post("/api/users", json={"email": "test@example.com", "name": "User 2"})
# 3. 断言期望结果
assert response.status_code == 409
assert "already exists" in response.json()["detail"]
GREEN Phase(最小实现)
# 只写让测试通过的最小代码
# 不要优化,不要添加额外功能
def create_user(db: Session, user: UserCreate):
existing = db.query(User).filter(User.email == user.email).first()
if existing:
raise HTTPException(status_code=409, detail="User already exists")
# ... 创建用户逻辑
REFACTOR Phase(重构)
# 改善代码结构
# 保持测试通过
# 消除重复
# 提取公共逻辑到服务层
质量门禁
| 检查项 | 标准 |
|---|---|
| 测试通过率 | 100% |
| 代码覆盖率 | >= 90% |
| 新代码覆盖率 | 100% |
| Lint (flake8) | 无错误 |
| TypeCheck (mypy) | 无错误 |
pytest 常用模式
Fixtures
@pytest.fixture
def db_session():
"""创建测试数据库会话"""
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
yield session
session.close()
@pytest.fixture
def client(db_session):
"""创建测试客户端"""
def override_get_db():
yield db_session
app.dependency_overrides[get_db] = override_get_db
return TestClient(app)
异步测试
import pytest
@pytest.mark.asyncio
async def test_async_operation():
result = await some_async_function()
assert result is not None
参数化测试
@pytest.mark.parametrize("status_code,detail", [
(400, "Invalid input"),
(404, "Not found"),
(409, "Already exists"),
])
def test_error_responses(client, status_code, detail):
# 测试多种错误场景
pass
常用命令
# 运行后端测试
make test TARGET=backend
# 运行特定测试
make test TARGET=backend FILTER=test_create_user
# 或使用 pytest 直接运行
pytest tests/ -k "test_create_user" -v
# 覆盖率检查
pytest --cov=app --cov-report=term-missing --cov-fail-under=90
# Lint 检查
flake8 app/ tests/
# 类型检查
mypy app/
# 完整 QA
make qa
相关文档
文档路径由配置指定(best_practices_dir),使用以下关键词搜索:
- 测试最佳实践:关键词 "testing", "pytest", "backend"
- 数据库操作:关键词 "database", "sqlalchemy", "transaction"
- API 设计:关键词 "api", "endpoint", "fastapi"
- 问题诊断:关键词 "troubleshooting", "debugging"
Weekly Installs
2
Repository
penkzhou/swiss-…e-pluginGitHub Stars
2
First Seen
Jan 27, 2026
Security Audits
Installed on
mcpjam2
neovate2
antigravity2
qwen-code2
windsurf2
zencoder2