Files
hotime/.cursor/plans/重写api测试框架文档_48c87f92.plan.md
T
hoteas 37a67f5810 feat(api): 增强 API 测试框架功能与文档
- 在 Api 结构中新增 lastResp 字段以存储最近请求的响应
- 添加 Verify 方法,支持自定义校验函数并返回 ApiCase 构建器
- 新增 Resp 方法,获取最近一次请求的响应以便于断言
- 在 TestCollector 中添加 Visited 字段,记录已调用的路径
- 更新 GenerateSwagger 方法,支持部分运行时保留未运行端点的已有数据
- 完善文档,增加用例编写范式和示例,提升测试框架的可用性与易用性
2026-03-30 01:55:07 +08:00

146 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: 重写API测试框架文档
overview: 重新编撰 Testing_API测试框架.md,以"错误用例先行 → 准备数据 → 正确请求(含响应断言+DB校验)"的完整流程为核心范式,让文档成为可直接照搬的编写指南。
todos:
- id: rewrite-doc
content: 重写 docs/Testing_API测试框架.md:错误用例先行 → 模拟数据准备 → 正确请求(响应断言必须+DB校验) → 逐步讲解各环节 → API速查表 → 其余章节微调
status: completed
isProject: false
---
# 重写 API 测试框架文档
## 用户确认的编写规范
1. **顺序**:先写错误请求用例,再写正确请求用例
2. **错误用例**:三个参数必须填满 `Post("描述", status, "具体错误消息")`,因为错误码是复用的(如 status=3 可能对应多种参数校验错误)
3. **正确请求前**:用 `a.DB()` 模拟插入数据,既准备测试依赖数据,也可作为后续 DB 校验的对照
4. **响应字段断言**:正确响应情况下**必须**断言(至少覆盖重要字段),不能只写 `Post("描述", 0)`
5. **数据库校验**:只要接口改变了数据库状态,都**建议**用 Verify 校验结果
## 标准用例编写流程(范式)
```
错误用例(参数校验、权限校验等)
准备测试数据(a.DB().Insert/Update 模拟前置数据)
正确请求 + 响应结构校验(ExpectResult / 第三参数 Map
响应字段断言(resp.GetBody() 检查关键业务字段)
数据库状态校验(Verify 查库确认写入/更新结果)
```
## 核心范例(贯穿文档的"创建订单"示例)
以下为快速开始中使用的完整范例,展示从业务代码到测试用例的映射:
```go
// order_test.go
var OrderTest = CtrTest{
"create": {Desc: "创建订单", Func: func(a *Api) {
// ======== 第一步:错误用例 ========
// 错误码复用,三个参数都必须填满
a.JSON(Map{"goods_id": int64(1), "quantity": 3, "address": "XX路1号"}).
Post("未登录创建订单", 2, "请先登录")
a.WithSession(Map{"user_id": int64(1)}).
JSON(Map{"quantity": 3, "address": "XX路1号"}).
Post("缺少商品ID", 3, "请选择商品")
a.WithSession(Map{"user_id": int64(1)}).
JSON(Map{"goods_id": int64(1), "address": "XX路1号"}).
Post("缺少数量", 3, "请填写购买数量")
a.WithSession(Map{"user_id": int64(1)}).
JSON(Map{"goods_id": int64(999), "quantity": 3, "address": "XX路1号"}).
Post("商品不存在", 4, "商品不存在")
// ======== 第二步:准备测试数据 ========
// 插入一条商品数据,后面的正确请求会依赖它
goodsId := a.DB().Insert("goods", Map{
"name": "测试商品", "price": 29.9, "stock": 100, "state": 1,
})
// ======== 第三步:正确请求 + 响应断言 + DB校验 ========
resp := a.WithSession(Map{"user_id": int64(1)}).
JSON(Map{"goods_id": goodsId, "quantity": 3, "address": "XX路1号"}).
Verify(func(a *Api) error {
row := a.DB().Get("order", "*", Map{"AND": Map{
"user_id": int64(1), "goods_id": goodsId,
}})
if row == nil {
return fmt.Errorf("order 表未写入订单记录")
}
if row.GetCeilInt64("state") != 0 {
return fmt.Errorf("新订单 state 期望 0, 实际 %d", row.GetCeilInt64("state"))
}
if row.GetCeilFloat64("total_price") != 29.9*3 {
return fmt.Errorf("total_price 期望 %.2f, 实际 %.2f", 29.9*3, row.GetCeilFloat64("total_price"))
}
// 校验库存扣减
goods := a.DB().Get("goods", "stock", Map{"id": goodsId})
if goods.GetCeilInt64("stock") != 97 {
return fmt.Errorf("库存期望 97, 实际 %d", goods.GetCeilInt64("stock"))
}
return nil
}).
Post("正常创建订单", 0, Map{
"id": int64(1), "sn": "sample", "total_price": float64(1.0),
})
// 关键业务字段断言
orderId := resp.GetBody().GetMap("result").GetCeilInt64("id")
if orderId <= 0 {
resp.Fail("返回的订单 ID 必须大于 0")
}
sn := resp.GetBody().GetMap("result").GetString("sn")
if sn == "" {
resp.Fail("返回的订单编号 sn 不能为空")
}
}},
}
```
## 文档结构
### 不变章节(微调措辞)
- 概述(能力表格)
- 核心类型
- 链式 API 参考(在 expect 参数规则部分强调:错误用例建议三参数写满)
- 事务隔离机制
- 覆盖率报告
- API 调试控制台
- 指定运行范围
- 并发保护与缓存隔离
- 框架改动说明
### 重写/新增章节
#### 1. "快速开始" — 使用上述完整范例
- 先展示业务代码(handler),再展示测试代码
- 范例中完整体现五步流程
- 目录结构、注册方式、运行方式保持原有说明
#### 2. "用例编写范式" — 新增章节,替代原"完整场景对照"
按顺序逐步讲解范例中的每个环节:
- **错误用例编写规范**:为什么三参数必须写满(错误码复用)、如何覆盖权限/参数/业务错误
- **测试数据准备**`a.DB().Insert()` 的使用场景和注意事项(事务内操作,自动回滚)
- **正确请求 + 响应结构校验**:第三参数 Map 的类型样本规则、ExpectResult 后置校验
- **响应字段断言**`resp.GetBody()` / `resp.Fail()` 的用法、哪些字段必须断言
- **数据库状态校验**:Verify 的使用时机(只要改了DB就建议校验)、校验主表+关联表+字段值
- 包含"不好的写法 vs 推荐的写法"对比
#### 3. "API 速查表" — 精简版场景对照
保留各种参数组合(JSON/Form/Query/File/混合/Session 等)的快速参考,但每种只一行示例代码,不再是大段散乱的代码块。
## 改动范围
- 仅改动 `docs/Testing_API测试框架.md`,约 750-850 行
- 不涉及 Go 源码
- 不涉及其他文档