backend-bugfix

📁 penkzhou/swiss-army-knife-plugin 📅 Jan 27, 2026
1
总安装量
1
周安装量
#50968
全站排名
安装命令
npx skills add https://github.com/penkzhou/swiss-army-knife-plugin --skill backend-bugfix

Agent 安装分布

mcpjam 1
claude-code 1
windsurf 1
crush 1
cline 1

Skill 文档

Backend Bugfix Workflow Skill

本 skill 提供后端测试 bugfix 的完整工作流知识,包括错误分类体系、置信度评分系统和 TDD 最佳实践。

错误分类体系

后端测试失败主要分为以下类型(按频率排序):

1. 数据库错误(30%)

症状:数据库连接失败、查询错误、事务问题

识别特征:

  • IntegrityError、OperationalError
  • sqlalchemy.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 不匹配

识别特征:

  • ValidationError
  • pydantic.error_wrappers
  • 422 Unprocessable Entity
  • field 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%)

症状:端点返回错误状态码、路由不匹配

识别特征:

  • HTTPException
  • 404 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 Unauthorized
  • 403 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%)

症状:异步操作超时、并发问题

识别特征:

  • TimeoutError
  • CancelledError
  • asyncio 相关异常
  • 缺少 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%)

症状:配置加载失败、环境变量缺失

识别特征:

  • KeyError
  • environment 相关错误
  • 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”