配置 SSOT(TOML + .env) 统一错误契约 Auth 与事务边界 Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client 可观测性(OpenTelemetry + LGTM)
50 lines
2.8 KiB
Plaintext
50 lines
2.8 KiB
Plaintext
---
|
||
description: Backend testing strategy for meaningful business coverage
|
||
globs: api/**/*
|
||
alwaysApply: false
|
||
---
|
||
|
||
# Backend Testing Strategy
|
||
|
||
- 测试必须服务真实业务场景,禁止为了覆盖率、形式化 TDD 或“顺手测一下”而堆低价值用例。
|
||
- 自动化优先覆盖:核心用户流程、鉴权/权限/配额/幂等、关键状态写入后的持久化结果、前端依赖的稳定 HTTP 契约。
|
||
- 不优先覆盖:第三方库自身行为、纯实现细节、脆弱的调用顺序断言、低价值 getter/常量映射。
|
||
- 默认优先写 HTTP 场景测试,而不是先写大量细碎单元测试。
|
||
|
||
## Test Infrastructure
|
||
|
||
- 不要直接 import `api/main.py` 跑测试;避免把 `.env`、startup/shutdown、Redis、模型预热等副作用带进测试。
|
||
- 优先使用最小 `FastAPI()` 测试 app,按需挂载目标 router。
|
||
- 用 `app.dependency_overrides` 替换数据库和外部依赖。
|
||
- 用 `httpx.AsyncClient` + `ASGITransport` 进行异步 HTTP 测试。
|
||
- `api/tests/conftest.py` 和 `api/tests/factories.py` 只提供通用基础设施,不要把具体业务测试硬编码进去。
|
||
|
||
## HTTP 错误契约
|
||
|
||
- 失败响应断言 **`error_code` + `message`**(及可选 `request_id`),不要断言 FastAPI 旧格式 `{ detail }`。
|
||
- OpenAPI / router 级 smoke:参考 `tests/test_http_router_error_contract.py`、`tests/test_openapi_error_response.py`。
|
||
- Auth / payment / SMS 等 feature 码:断言具体 `error_code`(如 `INVALID_SMS_CODE`、`REFRESH_TOKEN_REUSE`),不只测 status code。
|
||
|
||
## 配置 / TOML 测试
|
||
|
||
- TOML 加载测试用 `CONFIG_DIR` 指向 fixture 目录,或 `reload_app_config()`;见 `tests/test_app_config_loader.py`。
|
||
- **不要**用 `os.environ["OTEL_ENABLED"]` 等已迁出 Settings 的 env 键驱动应用行为(运行时已读 TOML)。
|
||
- 新增 TOML 默认值时,若影响产品行为,更新 `tests/test_default_toml_legacy_parity.py` 或明确 overlay 意图。
|
||
|
||
## Test Layering
|
||
|
||
- HTTP 场景测试:注册、登录、刷新、登出、受保护资源访问、关键资源 CRUD、重要失败分支。
|
||
- 纯单元测试:纯函数、规则计算、序列化、适配器错误分支与格式转换。
|
||
- Service / 事务边界测试:仅当保护明确业务承诺(如 refresh rotation、SMS 回滚、幂等 ingest)且 HTTP 层难以稳定复现时允许;参考 `tests/test_auth_refresh_rotation.py`、`tests/test_db_transactional.py`。
|
||
- 手工 / E2E:WebSocket 多轮对话、真实短信、Celery + Redis + LLM 编排、支付/对象存储/ASR/图像生成联调。
|
||
|
||
## Decision Filter
|
||
|
||
新增测试前先问自己:
|
||
|
||
1. 这个测试保护的是哪条业务承诺?
|
||
2. 失败后能否快速定位问题边界?
|
||
3. 这个测试是否比只测内部函数更接近真实用户行为?
|
||
|
||
如果答不上来 2 个以上,通常不该立刻写这个测试。
|