| name | backend-bugfix |
| description | This skill should be used when the user asks to "debug backend tests", "fix pytest failures", "analyze Python errors", "fix FastAPI bugs", or mentions keywords like "pytest", "IntegrityError", "ValidationError", "SQLAlchemy", "FastAPI". It provides the complete bugfix workflow knowledge including error classification, confidence scoring, and TDD best practices for Python/FastAPI backends.
|
| version | 2.1.0 |
Backend Bugfix Workflow Skill
本 skill 提供后端测试 bugfix 的完整工作流知识,包括错误分类体系、置信度评分系统和 TDD 最佳实践。
错误分类体系
后端测试失败主要分为以下类型(按频率排序):
1. 数据库错误(30%)
症状:数据库连接失败、查询错误、事务问题
识别特征:
IntegrityError、OperationalError
sqlalchemy.exc.* 异常
UNIQUE constraint failed
- 事务未提交或未回滚
解决策略:正确处理事务边界
def create_user(db: Session, user: UserCreate):
db_user = User(**user.dict())
db.add(db_user)
db.commit()
return db_user
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
class UserCreate(BaseModel):
email: str
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 处理
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
async def get_data():
result = fetch_from_external_api()
return result
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"""
client.post("/api/users", json={"email": "test@example.com", "name": "User 1"})
response = client.post("/api/users", json={"email": "test@example.com", "name": "User 2"})
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 tests/ -k "test_create_user" -v
pytest --cov=app --cov-report=term-missing --cov-fail-under=90
flake8 app/ tests/
mypy app/
make qa
相关文档
文档路径由配置指定(best_practices_dir),使用以下关键词搜索:
- 测试最佳实践:关键词 "testing", "pytest", "backend"
- 数据库操作:关键词 "database", "sqlalchemy", "transaction"
- API 设计:关键词 "api", "endpoint", "fastapi"
- 问题诊断:关键词 "troubleshooting", "debugging"