diff --git a/README.md b/README.md index 66ed04c..16c3ae6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +# 小帮菜后端 +测试方法 +D:\app\go1.23.1\bin\go.exe test ./dd/... -v + + # HoTime **高性能 Go Web 服务框架** diff --git a/docs/ROADMAP_改进规划.md b/docs/ROADMAP_改进规划.md index 7878afa..b22aab3 100644 --- a/docs/ROADMAP_改进规划.md +++ b/docs/ROADMAP_改进规划.md @@ -165,11 +165,105 @@ CREATE TABLE `_operation_log` ( --- +--- + +## 七、测试框架:响应字段断言(部分匹配) + +### 现状 + +`Post` / `Get` 等终端方法目前只支持断言响应体中的 `status` 和 `msg` 字段: + +```go +a.JSON(Map{"phone": phone, "password": "123456"}).Post("正常登录", 0) +a.JSON(Map{"phone": phone, "password": "123456"}).Post("密码为空", 4, "用户名或密码不能为空") +``` + +如需验证响应 `result` 内部的具体字段,只能手动写: + +```go +resp := a.JSON(Map{...}).Post("查询列表", 0) +if resp.GetBody().GetMap("result").GetInt("total") != 10 { + resp.Fail("total 应为 10") +} +``` + +这种写法冗长、可读性差,且失败时无法显示期望值与实际值的对比。 + +### 改进方向 + +在终端方法签名中增加**可选的响应字段部分匹配参数**: + +```go +// 现有签名(不变) +func (c *ApiCase) Post(desc string, status int, msg ...string) *ApiResponse + +// 新增重载或扩展参数,支持传入期望的 result 字段(Map 类型) +a.JSON(Map{...}).Post("查询列表", 0, Map{"total": 10}) +a.JSON(Map{...}).Post("查询列表", 0, Map{"total": 10, "list": notEmpty}) +a.JSON(Map{...}).Post("正常登录", 0, Map{"token": notEmpty}) +``` + +### 核心设计原则 + +**部分匹配,而非精确匹配**: + +- 只验证期望 Map 中列出的字段,响应中额外的字段不报错 +- 避免因响应新增字段导致测试频繁失败,降低维护成本 +- 精确匹配适合快照测试场景,但与"快速精准"目标相悖,不引入 + +### 支持的断言值类型 + +| 断言值 | 含义 | 示例 | +|--------|------|------| +| 具体值(string/int/bool) | 字段等于该值 | `Map{"total": 10}` | +| `notEmpty`(特殊常量) | 字段存在且非空/非零 | `Map{"token": notEmpty}` | +| 嵌套 Map | 递归部分匹配子对象 | `Map{"user": Map{"id": 1}}` | + +### 预期写法 + +```go +// 断言 total 值 +a.Query(Map{"page": "1"}).Get("查询列表", 0, Map{"total": 5}) + +// 断言 token 字段存在且非空(不关心具体值) +resp := a.JSON(Map{"phone": "138...", "password": "123456"}).Post("正常登录", 0, Map{"token": notEmpty}) + +// 组合:status + msg + result 字段三合一 +a.JSON(Map{"phone": ""}).Post("手机号为空", 4, "手机号不能为空") // 只验 status+msg +a.JSON(Map{"phone": "138..."}).Post("正常注册", 0, Map{"id": notEmpty}) // 验 status + result.id +``` + +### 失败输出格式 + +失败时应显示期望值和实际值对比,便于快速定位: + +``` +--- FAIL: TestApi/app/user/login/正常登录 + 期望 result.token 非空,实际值为 "" + 期望 result.total = 10,实际值为 0 +``` + +### 实现要点 + +- 参数类型可设计为 `...interface{}`,兼容现有 `msg ...string` 的调用方式,通过类型断言区分 +- `notEmpty` 可定义为框架内的特殊常量(如 `var notEmpty = struct{}{}`) +- 断言逻辑复用 `ApiResponse` 已有的 `GetBody()` 链路,递归遍历期望 Map + +### 待确认 + +- [ ] 终端方法签名如何兼容:新增第四参数 `result Map`,还是利用 `...interface{}` 统一 +- [ ] `notEmpty` 常量的导出名称和定义位置 +- [ ] 嵌套 Map 递归断言是否纳入首批实现范围 +- [ ] 失败输出是否需要完整响应体 dump + +--- + ## 改进优先级 | 优先级 | 改进项 | 状态 | |--------|--------|------| | 高 | 备注语法优化(`\|` 分隔符) | 待设计 | +| 高 | 测试框架:响应字段部分匹配断言 | 待实现 | | 中 | 软删除/日志表支持 | 待设计 | | 低 | 多对多关联表增强 | 待评估 | | 低 | 自动填充字段扩展 | 待评估 | @@ -181,3 +275,4 @@ CREATE TABLE `_operation_log` ( | 日期 | 内容 | |------|------| | 2026-01-24 | 初始版本,记录分析结果和待改进项 | +| 2026-03-15 | 新增测试框架响应字段断言改进规划(七) |