新增禅道项目管理系统插件,含项目集/产品/项目/执行、需求 (story/epic/requirement)、Bug、任务、测试、计划与发布、反馈工单 八个工作流技能,自动配置 MCP 连接(禅道「个人中心 → 获取凭证」 自助生成 14 天 Token)。 MCP Server 是团队自建的 zentao-mcp 网桥(部署在 pm.ops.yixiong-tech.com/mcp),基于开源 openapi-mcp-server 二次开发。 Claude 侧走 userConfig 钥匙链 + 自定义 token 头;Codex 侧受限于官方 插件格式只支持 bearer_token_env_var,走 Authorization: Bearer——网桥 那边已经加了 preferred_header/bearer_mode 配置项统一归一化处理,两条 路径都验证过连通。 三轮审查(静态字段对照 openapi.json、跨文件一致性、真实端点实测) 修正过程中发现的问题,技能文档里引用的工具名全部跟服务器真实注册 的 118 个工具核对过。 同步更新:.claude-plugin/marketplace.json、.agents/plugins/marketplace.json、 README.md、CLAUDE.md 的插件索引与说明;README 补充「获取凭证」操作 截图(已脱敏)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016pFx6jnym6kRWRQ5JyDUNv
123 lines
5.1 KiB
Markdown
123 lines
5.1 KiB
Markdown
---
|
||
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 })
|
||
```
|
||
|
||
删除不可逆,执行前必须确认。
|