feat(api): 增强 API 测试框架功能与文档
- 在 Api 结构中新增 lastResp 字段以存储最近请求的响应 - 添加 Verify 方法,支持自定义校验函数并返回 ApiCase 构建器 - 新增 Resp 方法,获取最近一次请求的响应以便于断言 - 在 TestCollector 中添加 Visited 字段,记录已调用的路径 - 更新 GenerateSwagger 方法,支持部分运行时保留未运行端点的已有数据 - 完善文档,增加用例编写范式和示例,提升测试框架的可用性与易用性
This commit is contained in:
+173
-10
@@ -1,18 +1,181 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
. "code.hoteas.com/golang/hotime"
|
||||
. "code.hoteas.com/golang/hotime/common"
|
||||
)
|
||||
|
||||
var TestTest = CtrTest{
|
||||
"all": {Desc: "运行全部通用测试", Func: func(a *Api) { a.Get("全部测试", 0) }},
|
||||
"crud": {Desc: "基础 CRUD 测试", Func: func(a *Api) { a.Get("CRUD测试", 0) }},
|
||||
"condition": {Desc: "条件查询语法测试", Func: func(a *Api) { a.Get("条件查询", 0) }},
|
||||
"chain": {Desc: "链式查询测试", Func: func(a *Api) { a.Get("链式查询", 0) }},
|
||||
"join": {Desc: "JOIN 查询测试", Func: func(a *Api) { a.Get("JOIN查询", 0) }},
|
||||
"aggregate": {Desc: "聚合函数测试", Func: func(a *Api) { a.Get("聚合函数", 0) }},
|
||||
"pagination": {Desc: "分页查询测试", Func: func(a *Api) { a.Get("分页查询", 0) }},
|
||||
"batch": {Desc: "批量插入测试", Func: func(a *Api) { a.Get("批量插入", 0) }},
|
||||
"upsert": {Desc: "Upsert 测试", Func: func(a *Api) { a.Get("Upsert测试", 0) }},
|
||||
"transaction": {Desc: "事务测试", Func: func(a *Api) { a.Get("事务测试", 0) }},
|
||||
// ======== 错误接口测试 ========
|
||||
"test": {Desc: "固定错误返回", Func: func(a *Api) {
|
||||
a.Get("固定返回错误码2", 2, "dsadasd")
|
||||
}},
|
||||
|
||||
// ======== ORM 全量测试 ========
|
||||
"all": {Desc: "运行全部通用测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
result := a.Resp().GetBody().GetMap("result")
|
||||
if result == nil {
|
||||
return fmt.Errorf("result 为 nil")
|
||||
}
|
||||
subTests := []string{
|
||||
"1_basic_crud", "2_condition_syntax", "3_chain_query",
|
||||
"4_join_query", "5_aggregate", "6_pagination",
|
||||
"7_batch_insert", "8_upsert", "9_transaction",
|
||||
}
|
||||
for _, key := range subTests {
|
||||
sub := result.GetMap(key)
|
||||
if sub == nil {
|
||||
return fmt.Errorf("子测试 %s 缺失", key)
|
||||
}
|
||||
if sub.GetString("name") == "" {
|
||||
return fmt.Errorf("子测试 %s 缺少 name 字段", key)
|
||||
}
|
||||
tests := sub.GetSlice("tests")
|
||||
if len(tests) == 0 {
|
||||
return fmt.Errorf("子测试 %s 的 tests 数组为空", key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}).Get("全部测试", 0, Map{
|
||||
"1_basic_crud": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample", "result": true}},
|
||||
},
|
||||
"2_condition_syntax": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample", "result": true}},
|
||||
},
|
||||
"3_chain_query": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
"4_join_query": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
"5_aggregate": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
"6_pagination": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
"7_batch_insert": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
"8_upsert": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
"9_transaction": Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
},
|
||||
})
|
||||
}},
|
||||
|
||||
// ======== 单项 ORM 测试 ========
|
||||
"crud": {Desc: "基础 CRUD 测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "基础CRUD测试")
|
||||
}).Get("CRUD测试", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample", "result": true}},
|
||||
})
|
||||
}},
|
||||
|
||||
"condition": {Desc: "条件查询语法测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "条件查询语法测试")
|
||||
}).Get("条件查询", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample", "result": true}},
|
||||
})
|
||||
}},
|
||||
|
||||
"chain": {Desc: "链式查询测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "链式查询测试")
|
||||
}).Get("链式查询", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
|
||||
"join": {Desc: "JOIN 查询测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "JOIN查询测试")
|
||||
}).Get("JOIN查询", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
|
||||
"aggregate": {Desc: "聚合函数测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "聚合函数测试")
|
||||
}).Get("聚合函数", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
|
||||
"pagination": {Desc: "分页查询测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "分页查询测试")
|
||||
}).Get("分页查询", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
|
||||
"batch": {Desc: "批量插入测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "批量插入测试")
|
||||
}).Get("批量插入", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
|
||||
"upsert": {Desc: "Upsert 测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "Upsert测试")
|
||||
}).Get("Upsert测试", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
|
||||
"transaction": {Desc: "事务测试", Func: func(a *Api) {
|
||||
a.Verify(func(a *Api) error {
|
||||
return verifyOrmSubTest(a, "事务测试")
|
||||
}).Get("事务测试", 0, Map{
|
||||
"name": "sample", "success": true,
|
||||
"tests": Slice{Map{"name": "sample"}},
|
||||
})
|
||||
}},
|
||||
}
|
||||
|
||||
// verifyOrmSubTest 校验 ORM 自测端点的结构完整性
|
||||
// 注意:这些 handler 是诊断工具,某些子项(如 table.column 格式聚合)在特定数据库下
|
||||
// 预期 result=false,因此不逐项检查 result 标志,只验证结构
|
||||
func verifyOrmSubTest(a *Api, testName string) error {
|
||||
result := a.Resp().GetBody().GetMap("result")
|
||||
if result == nil {
|
||||
return fmt.Errorf("result 为 nil")
|
||||
}
|
||||
if result.GetString("name") == "" {
|
||||
return fmt.Errorf("%s 缺少 name 字段", testName)
|
||||
}
|
||||
tests := result.GetSlice("tests")
|
||||
if len(tests) == 0 {
|
||||
return fmt.Errorf("%s tests 数组为空", testName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user