--- name: zentao-test description: "禅道测试管理:创建/查询/修改测试用例(含步骤设计)、创建测试单提测。当用户说「写个测试用例」「设计测试步骤」「提测」「建个测试单」「查测试用例」时使用。" --- # 禅道测试管理(testcase / testtask) **前置:先读 `zentao-shared`(尤其"路径参数不出现在 inputSchema 里"一节)。** 测试相关是高频场景——测试同学写用例、开发/测试提测,这个技能覆盖得比其他业务域更细, 尤其是 testcase 的步骤结构,是全部 8 个技能里**唯一一处需要特别小心的嵌套/对应关系**。 --- ## 测试用例(testcase) ### 详情接口的路径参数命名例外(跟 zentao-story 的 storyID 是同类坑) ``` get_testcases_caseID(caseID) 详情:参数字面叫 caseID put_testcases_testcasID(...) 修改:参数字面叫 testcasID(注意,是 testcasID 不是 testcaseID,少一个 e) delete_testcases_testcasID(...) 删除:同上 ``` 三个接口的路径参数名互相都不一样(`caseID` / `testcasID`),且 `testcasID` 是官方 API 的拼写(缺了一个 `e`),**照抄字面参数名,不要自己纠正拼写**,传错名字会静默返回空结果。 ### 查 ``` get_products_productID_testcases(productID, ...) get_projects_projectID_testcases(projectID, ...) get_executions_executionID_testcases(executionID, ...) get_testcases_caseID(caseID) 详情 ``` ### 建——步骤是三个平行数组,靠索引位置对应 ``` post_testcases({ payload: { productID, title, module?, story?, pri?, type?, precondition?, steps?: string[], # 步骤描述,第 i 项 expects?: string[], # 第 i 项步骤的期望结果 stepType?: string[], # 第 i 项步骤的类型:step 步骤 | group 父级步骤(分组标题,无需期望结果) project?, execution? } }) ``` **这不是一个"步骤对象数组"(不是 `[{step, expect, type}, ...]`),是三个独立的字符串 数组,`steps[i]`/`expects[i]`/`stepType[i]` 靠同一个下标 `i` 对应同一个步骤。** 三个 数组长度必须一致,写用例时先把步骤列成一个表格跟用户确认,再按顺序拆成三个数组传, 不要把某一步的期望结果错位对到别的步骤上——这种错位不会报错,只会在用例详情里显示 "驴唇不对马嘴",很难事后发现。 `stepType` 为 `group` 的行是分组标题(比如"登录流程"这种大标题),对应的 `expects[i]` 一般传空字符串。 举例——"登录"用例有一个分组、两个步骤: ``` steps = ["登录流程", "打开登录页,输入正确账号密码", "点击登录按钮"] stepType = ["group", "step", "step"] expects = ["", "账号密码输入框正常显示", "跳转到首页,显示欢迎语"] ``` `type`(用例类型)受限枚举:`unit` 单元测试 | `interface` 接口测试 | `feature` 功能测试 | `install` 安装部署 | `config` 配置相关 | `performance` 性能测试 | `security` 安全相关 | `other` 其他。 ### 改 / 删 ``` put_testcases_testcasID({ testcasID, payload: {...} }) # 改步骤同样是三个数组整体替换,不是增量 delete_testcases_testcasID({ testcasID }) ``` 改步骤时**传的是完整的三个新数组,不是"追加一步"**——想加一个步骤,要先 `get_testcases_caseID` 拿到现有的 steps/expects/stepType,在末尾追加后整体传回,跟 `huanxi-task` 里 `task_set_assignees` 整组覆盖是同一种坑,直接传一步会把其余步骤全部覆盖掉。 --- ## 测试单(testtask,提测) **没有单条测试单详情接口**(只有创建/修改/删除,没有 `get_testtasks_testtaskID`),要看 某个测试单的信息,从列表接口里按 ID 过滤。 ### 查 ``` get_products_productID_testtasks(productID, ...) get_projects_projectID_testtasks(projectID, ...) get_executions_executionID_testtasks(executionID, ...) ``` ### 建 ``` post_testtasks({ payload: { productID, name, build, begin, end, execution?, type?, owner?, status?, desc? } }) ``` `productID`/`name`/`build`(提测构建/版本)/`begin`/`end` 必填。 **`type`(测试类型)是字符串数组,不是单值**——一个测试单可以同时标多种测试类型,取值 受限:`integrate` 集成测试 | `system` 系统测试 | `acceptance` 验收测试 | `performance` 性能测试 | `safety` 安全测试。传的时候是 `type: ["integrate", "system"]` 这种数组形式,不要传成 单个字符串 `type: "integrate"`。 **跟其他实体不同,测试单的状态不是靠专门的 activate/close 端点切换,而是创建/修改时 直接传 `status` 字段**:`wait` 未开始 | `doing` 进行中 | `done` 已关闭 | `blocked` 被阻塞。 改状态就是 `put_testtasks_testtaskID({ testtaskID, payload: { status: "doing" } })`。 ### 改 / 删 ``` put_testtasks_testtaskID({ testtaskID, payload: {...} }) delete_testtasks_testtaskID({ testtaskID }) ``` 删除不可逆,执行前必须确认。