
Testany Case
- 16 installs
- 79 repo stars
- Updated May 6, 2026
- testany-io/testany-agent-skills
Helps with testing & qa tasks.
About
testany-case is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted development.
- testany-case
- Testing & QA
- AI-coding skill
Testany Case by the numbers
- 16 all-time installs (skills.sh)
- Ranked #1,468 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/testany-io/testany-agent-skills --skill testany-caseAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 16 |
|---|---|
| repo stars | ★ 79 |
| Last updated | May 6, 2026 |
| Repository | testany-io/testany-agent-skills ↗ |
What it does
Helps with testing & qa tasks.
Files
Testany Platform Case Registration & CRUD
本 skill 通过 Testany MCP 工具管理 Testany 平台上的 platform cases。 所有操作都是对 Testany 平台的远程 API 调用,不涉及本地文件系统。
关键前提:
- Testany
case是可复用原子自动化步骤包 - Testany 不支持直接执行单条 case
- 如果用户要真正执行,后续仍需要
testany-pipeline
用户输入: $ARGUMENTS
---
宿主能力适配
- 优先使用宿主提供的结构化提问工具(如 AskUserQuestion)一次性收集缺失信息。
- 如果宿主不支持该工具,则用一条普通消息集中提问相同问题;低风险字段可给出默认值建议。
- 如果宿主支持 slash command,可推荐相关 workflow 的命令入口;否则直接在当前线程继续对应 workflow。
---
先统一心智模型
使用本 skill 前,先按 automation-model.md 理解边界:
- 上游给出的通常是 traditional test scenario
testany-case-writing负责把它拆成 platform cases,并产出脚本、ZIP 与 decomposition- 本 skill 负责把这些 platform case packages 注册到 Testany 平台
testany-pipeline负责把 platform cases 组装成可执行 pipelinetestany-trigger负责配置Plan / Manual Trigger / Gatekeeper
重要结论:
- 本 skill 的主路径不应该是“现场理解业务场景并写 case”
- 本 skill 的主路径应该是“消费上游已准备好的 package / metadata / decomposition,完成平台注册与生命周期管理”
---
职责
- 注册
testany-case-writing已产出的 platform case packages - 创建 case shell、补齐 case metadata、上传脚本 ZIP
- 查询、更新、批量更新、删除平台上的 platform cases
- 在变更后提醒用户检查下游 pipeline 影响面
- 在可行时触发 dry run 验证 case 是否 ready
不负责的事情
- 不负责把传统测试场景拆解成 platform cases;这属于
testany-case-writing - 不负责创建或更新 pipeline;这属于
testany-pipeline - 不负责配置 Plan / Manual Trigger / Gatekeeper;这属于
testany-trigger
---
操作速查
| 用户意图 | 操作类型 | 工具 |
|---|---|---|
| 注册新的 platform case | Create | testany_create_case → testany_update_case → testany_update_case_script |
| 查看 case 详情 | Read | testany_get_case |
| 查看 case 脚本内容 | Read | testany_get_case_script |
| 搜索/列出 cases | Read | testany_list_cases |
| 列出我的 cases | Read | testany_list_my_cases |
| 更新 metadata / script | Update | testany_update_case / testany_update_case_script |
| 删除 case | Delete | testany_delete_case |
| 批量更新 cases | Bulk Update | testany_bulk_update_cases |
| 批量删除 cases | Bulk Delete | testany_bulk_delete_cases |
| dry run 验证 | Validate | testany_dry_run_case → testany_get_dry_run_result |
| 查看 dry run 日志 | Read | testany_get_dry_run_log(拼接出 logUrl + curlCommand,agent 代为执行) |
---
Create(注册新的 platform case)
Phase 0: 先判断输入模式
按以下优先级选择输入模式:
1. Primary:已有 platform case package
- 来自
testany-case-writing - 已准备好脚本、ZIP、metadata、executor 选择
- 最适合本 skill
2. Secondary:已有脚本/ZIP,但 metadata 不完整
- 可以在本 skill 中补齐名称、可见性、labels、case_meta 等字段
3. Fallback:只想先创建草稿 shell case
- 仅当用户明确要求占位、预留 key、先建空壳时使用
- 不能把它包装成“已经完成自动化落地”
如果用户只有传统测试场景,没有脚本、ZIP、decomposition:
- 停止直接创建
- 切到
testany-case-writing
Phase 1: 准备可选项
并行获取:
testany_filter_case_runtimestestany_get_my_workspacestestany_get_tenant_config(拿deployment_type,决定 visibility 默认值,见 case-visibility-policy.md)
如涉及 labels,先:
testany_list_labels- 如缺失再
testany_create_label
Phase 2: 收集注册所需字段
优先一次性收集以下内容:
| 字段 | 必填 | 说明 |
|---|---|---|
name | 是 | platform case 名称 |
runtime_uuid | 是 | 运行环境 UUID,推荐 cloudprime |
is_private | 是 | Global / Private — 受 `deployment_type` 约束,见 case-visibility-policy.md |
workspace_keys | 条件必填 | is_private=true 时必填;详见 policy 文档 |
description | 建议 | 说明该 platform case 的原子职责 |
case_labels | 建议 | 用于目录视图和检索 |
case_meta | 条件必填 | 运行所需配置,具体字段见 executors reference |
| ZIP / 脚本包 | 条件必填 | 若目标是注册 runnable case,通常需要 |
收集原则:
- 主路径假设用户已经有 package;本 skill 只做“平台注册与补齐元数据”
- 如果用户明确只要草稿 case,可暂不上传 ZIP,但必须明确这是占位资产,不可直接执行
Phase 3: 创建 shell case
调用 testany_create_case:
nameruntime_uuidis_privateworkspace_keys
Phase 4: 补齐 metadata / 运行配置
调用 testany_update_case 设置:
descriptioncase_labelsenvironmentsowned_bycase_versioncase_meta
这里的 case_meta 后端字段名仍然是 trigger_method,但它表示的是 case 级运行入口配置:
executortrigger_pathtrigger_command
它不等于 Plan / Manual Trigger / Gatekeeper 这类 pipeline trigger。
case_meta.environment_variables
case 运行时可见的变量列表,每条有一个 type:
| type | 用途 | 填值方式 |
|---|---|---|
env(默认) | 普通环境变量、relay 输入 | 填 value |
output | 供 pipeline 中其他 case relay 消费 | 填 value(运行时由脚本写入) |
secrets | 引用 workspace 的 Credential Safe 条目 | 填 secret_ref: { workspace_key, credential_safe_key, credential_key };禁止填 value |
关于 `type=secrets`:
- 声明后,脚本里直接用同名环境变量读取凭证值即可(例:
os.getenv("DB_PASSWORD")),不需要额外的取值代码或 SDK - 如果用户没有现成的
credential_safe_key/credential_key,用testany_list_credential_safes→testany_list_credential_keys两步查询(runtime_uuid必须与 case 一致;两个工具返回签名 curl,需 agent 代为执行)。详细流程见 executors.md 的"查询 credential_safe_key / credential_key" - 读回 case 时,每条 secrets 行附带只读字段
status(valid/blocked/invalid)和status_reasons[] - 非
valid要向用户报告原因。常见 reason:owner_access_not_satisfied(owner 没访问权)、visibility_not_satisfied(case 可见性收窄)、target_not_found_or_unresolvable(safe/key 不存在)、secret_ref_malformed(引用字段不完整) - 写入时不要传
value/status/status_reasons;传了会被后端拒绝 - 如果
testany_update_case/testany_bulk_update_cases/testany_bulk_append_cases返回错误码E400002(case_secrets_feature_disabled),向用户说明:当前 workspace 的 secrets 功能可能未开启,请联系 workspace 管理员
写入注意(整集合替换语义):environment_variables 是整数组替换。若只想新增或修改单条 secret,必须先 testany_get_case 读出现有条目,在内存里合并后再写回;否则其他 env / output / secrets 行会被一并清空。
详细字段规则见:
- Case 元数据规范
- Executor 配置详解
Phase 5: 上传脚本 ZIP
如果用户已经准备好脚本包,调用 testany_update_case_script 上传。
如脚本中包含以下能力,提醒用户同步补齐配置:
- Relay 输出 → 在
case_meta.environment_variables中声明对应的type=output行 - 凭证 / 敏感值访问 → 在
case_meta.environment_variables中声明type=secrets行 +secret_ref,脚本里直接读同名环境变量即可
Phase 6: 可选 dry run
如用户要求验证,或刚补齐了必填字段: 1. testany_dry_run_case 2. testany_get_dry_run_result 轮询直到进入终态 3. 如需排查(例如失败、想看实际 stdout),调 testany_get_dry_run_log 拿 curlCommand 后由 agent 代为执行拉取日志
Phase 7: 明确 downstream handoff
创建完成后,必须显式说明:
- 这是已注册的 platform case
- 如果用户要形成可执行链路,下一步需要
testany-pipeline - 即使只有一个 case,要在 Testany 中执行也仍需一条 pipeline
---
Read(查询)
| 场景 | 工具 | 说明 |
|---|---|---|
| 获取单个 case 详情 | testany_get_case | 传入 case key |
| 获取 case 脚本内容 | testany_get_case_script | 下载 ZIP 并返回文件内容 |
| 搜索所有 cases | testany_list_cases | 支持 workspace / keyword / page 等过滤 |
| 列出我的 cases | testany_list_my_cases | 适合个人资产盘点 |
---
Update(更新)
可更新的字段
| 字段 | 说明 |
|---|---|
name | case 名称 |
description | 原子职责说明 |
is_private | 可见性 |
workspace_keys | 私有 case 的工作空间列表 |
environments | 环境标签 |
case_labels | 分类标签 |
case_version | 版本号 |
owned_by | 所有者 |
case_meta | 运行配置 |
| 脚本 ZIP | 通过 testany_update_case_script 上传 |
更新流程
1. testany_get_case 获取当前配置 2. 确认要修改的字段 3. testany_update_case 提交 metadata 更新 4. 如需替换脚本,再 testany_update_case_script
Visibility 变更的特殊约束
is_private / workspace_keys 的更新受 deployment_type 约束:restricted → global 在 type=2 租户下会被拒(E400001)。见 case-visibility-policy.md。bulk_update_cases 走同一套校验。
必须提醒用户检查下游 pipeline 的情况
如果修改了以下内容,必须提示用户同步检查相关 pipeline:
- executor 相关配置
- 脚本入口或运行命令
- Relay 输出变量
- 输入环境变量名称
- 脚本内部行为导致的输入/输出变化
原因:
- pipeline 可能依赖该 case 的 relay、顺序或输入输出约定
- 平台 case 是可复用资产,case 变更可能影响多个 pipeline
如果用户下一步就要修这些引用关系,切到 testany-pipeline。
---
Delete(删除)
单个删除
调用 testany_delete_case 前,必须先明确告知用户:
- 如果该 case 已被编排到一个或多个 pipeline 中,平台会返回
409 - 需要先把该 case 从相关 pipeline 中移除,才能删除
- 如果该 case 是 Git 导入资产,也可能无法手动删除
当前限制:
- 如 MCP 侧没有现成的 “used by pipeline” 查询工具,则无法在删除前完全自动 preflight
- 因此应把删除结果视为“可能失败的受约束操作”,而不是无条件直删
如果删除失败并返回 409:
- 明确向用户解释原因
- 建议先去
testany-pipeline解除组装关系,再重试
批量删除
testany_bulk_delete_cases 同样受上述约束:
- 任何已被 pipeline 组装的 case 都会导致删除受阻
- 先提醒风险,再执行
---
Labels 与目录视图
Testany 使用 case_labels 实现虚拟目录结构:
- 一个 case 可以有多个 labels
- Labels 必须先存在,才能在 case 上引用
典型流程: 1. testany_list_labels 2. 如缺失,testany_create_label 3. testany_update_case / testany_bulk_update_cases / testany_bulk_append_cases
---
Dry Run(验证)
dry run 只验证 case 本身是否 ready,不替代 pipeline 编排验证。
流程: 1. testany_dry_run_case —— 触发 dry run,拿到 dry_run_id 2. testany_get_dry_run_result —— 轮询直到 dry_run_status 进入终态 3. (需要时)testany_get_dry_run_log —— 拼接 logUrl + 签名 curl,由 agent 代为执行拉日志
dry_run_status 与 execution status 共用同一套数值:
| 值 | 含义 | 是否终态 |
|---|---|---|
| -1 | NOT_STARTED(排队中) | 否 |
| 0 | RUNNING | 否 |
| 1 | SUCCESS | 是 |
| 2 | FAILURE | 是 |
| 5 | CANCELLED | 是 |
| 99 | ERROR | 是 |
常见误用:把 1 (SUCCESS) 当成 RUNNING 持续轮询。看到 1 就该停下来,要么报告成功、要么调 testany_get_dry_run_log 看输出。
典型用途:
- 新上传脚本后确认 case 已可运行
- 更新必填字段后确认配置完整
- 失败时通过
testany_get_dry_run_log看 stdout / 错误堆栈,定位是脚本 bug 还是配置 bug
---
常见问题处理
| 场景 | 处理方式 |
|---|---|
| 用户只有传统测试场景,没有 package | 先去 testany-case-writing |
| 用户要注册多个原子步骤 | 按 package inventory 逐个创建/更新 case |
| 用户希望形成可执行链路 | case 注册后继续到 testany-pipeline |
| 用户想删除 case | 先提醒 pipeline 组装约束与 409 风险 |
| 用户更新了 relay / 输入输出相关字段 | 提醒同步检查相关 pipeline |
---
返回格式
任务完成后,向用户汇报:
- Case Key(如
A1B2C3D4) - Case 名称
- 该 case 的原子职责
- 是否已上传脚本 ZIP
- 可见性(Global / Private + 工作空间列表)
- 是否已 dry run
- 下一步建议:
- 注册完成但尚未可执行 → 去
testany-pipeline - 已有 pipeline 但缺执行入口 → 去
testany-trigger
---
参考文档
- Testany 自动化对象模型
- Case 元数据规范
- Executor 配置详解
- 核心概念
interface:
display_name: "Testany Case"
short_description: "Register and manage Testany platform cases"
icon_small: "./assets/testany-logo-small.png"
icon_large: "./assets/testany-logo.svg"
default_prompt: "Use $testany-case to register, update, or inspect Testany platform cases."
Case 元数据规范
本规范定义了 Testany Test Case 元数据的填写标准。遵循此规范可以让后续的 Pipeline 编排(无论是人还是 AI)更加高效准确。
---
为什么需要这个规范
Pipeline 编排需要完成三个任务:
| 任务 | 需要的信息 |
|---|---|
| 选择 cases | 这个 case 测试什么功能/场景?关联哪个需求? |
| 确定顺序 | 这个 case 依赖什么前置条件? |
| 配置 Relay | 这个 case 需要什么输入?产生什么输出? |
如果 case 元数据不完整或不规范,编排者需要猜测或阅读脚本代码,增加工作量和出错概率。
---
字段映射规范
name(名称)
用途:简洁描述测试场景
格式:[动作] [对象] [可选:条件/结果]
示例:
✅ 订阅 Gallery Item 并验证资源创建
✅ 登录成功并获取 Token
✅ 编辑订阅资源被拒绝(只读约束)
❌ test_001
❌ 测试
❌ US-G006---
case_labels(标签)
用途:结构化分类,支持精确筛选
必须包含: 1. User Story 编号(如有关联需求) 2. 功能模块 3. 测试类型(可选)
格式:
["US-G006", "subscription", "gallery", "smoke"]| 位置 | 内容 | 示例 |
|---|---|---|
| 第 1 个 | User Story 编号 | US-G006, US-G007 |
| 第 2-N 个 | 功能模块 | subscription, gallery, login, payment |
| 最后 | 测试类型(可选) | smoke, regression, e2e |
示例:
✅ ["US-G006", "subscription", "gallery"]
✅ ["US-G001", "gallery", "browse", "smoke"]
✅ ["login", "auth", "regression"] // 无关联 US 时省略
❌ ["test"]
❌ []---
description(描述)
用途:自然语言描述,包含测试场景和前置条件
必须包含: 1. 测试场景:测试什么、验证什么 2. 前置条件:依赖什么状态或其他 case
格式模板:
[一句话描述测试场景]
验证点:
- [验证点 1]
- [验证点 2]
- ...
前置条件:[描述依赖的状态或 case]示例:
测试用户订阅 Gallery Item 后系统正确创建资源。
验证点:
- 资源创建成功(status 200)
- source = 'subscribed'
- source_gallery_item_id 指向正确的 Gallery Item
- subscribed_version 记录当前版本号
前置条件:需要登录状态(AUTH_TOKEN 来自 LOGIN case)简化版(适用于简单 case):
测试用户登录成功并获取认证令牌。
前置条件:无---
environment_variables(环境变量)
用途:定义 case 运行时可见的变量及其语义
类型(`type`):
env(默认):普通环境变量、pipeline relay 的输入output:输出变量,供 pipeline 中其他 case relay 消费secrets:引用 workspace Credential Safe 条目;声明后脚本里直接读同名环境变量即可
必须填写 `description` 字段,说明:
- 变量的含义
- 对于
type=env:数据来源(来自哪个 case / 固定值 / relay) - 对于
type=output:数据用途(供哪些 case 使用) - 对于
type=secrets:凭证用途(用于访问什么资源)
格式:
type=env / type=output — 填 value:
{
"name": "VARIABLE_NAME",
"type": "env",
"value": "-",
"description": "变量语义说明"
}type=secrets — 填 secret_ref(禁止填 value):
{
"name": "VARIABLE_NAME",
"type": "secrets",
"secret_ref": {
"workspace_key": "WKS",
"credential_safe_key": "WKS-CS-0001",
"credential_key": "credential-identifier"
},
"description": "凭证语义说明"
}如何解析 `credential_safe_key` / `credential_key`:用testany_list_credential_safes→testany_list_credential_keys两步 MCP 工具查询,传入与 case 相同的runtime_uuid;取返回项的key字段(不是name)。完整流程见 executors.md 的"查询 credential_safe_key / credential_key"一节。
示例:
输入变量(type=env):
{
"name": "AUTH_TOKEN",
"type": "env",
"value": "-",
"description": "登录认证令牌,来自 LOGIN case 的输出"
}输出变量(type=output):
{
"name": "RESOURCE_ID",
"type": "output",
"value": "-",
"description": "创建的订阅资源 ID,供 READONLY_CHECK 和 INSTRUCTION_CHECK cases 使用"
}secret 变量(type=secrets):
{
"name": "API_KEY",
"type": "secrets",
"secret_ref": {
"workspace_key": "WKS",
"credential_safe_key": "WKS-CS-0001",
"credential_key": "prod-api-key"
},
"description": "上游 API 的访问凭证"
}错误示例:
❌ { "name": "TOKEN", "type": "env", "value": "-" } // 缺少 description
❌ { "name": "X", "type": "output", "value": "-", "description": "输出" } // description 无意义
❌ { "name": "KEY", "type": "secrets", "value": "abc" } // secrets 禁止填 value
❌ { "name": "KEY", "type": "secrets" } // secrets 缺少 secret_ref
❌ { "name": "KEY", "type": "secrets", "secret_ref": { "workspace_key": "W" } } // secret_ref 三个字段都必填读时只读字段:读回 case 时,每条secrets行附带status(valid/blocked/invalid)和status_reasons[];写入时不要传这两个字段。非valid要向用户说明原因。
---
完整示例
Case: 订阅 Gallery Item
name: 订阅 Gallery Item 并验证资源创建
case_labels:
- US-G006
- subscription
- gallery
description: |
测试用户订阅 Gallery Item 后系统正确创建资源。
验证点:
- 资源创建成功
- source = 'subscribed'
- source_gallery_item_id 正确
- subscribed_version 记录正确
前置条件:需要登录状态(AUTH_TOKEN 来自 LOGIN case)
environment_variables:
- name: AUTH_TOKEN
type: env
value: "-"
description: 登录认证令牌,来自 LOGIN case 的输出
- name: GALLERY_ITEM_ID
type: env
value: "test-item-001"
description: 要订阅的 Gallery Item ID
- name: RESOURCE_ID
type: output
value: "-"
description: 创建的订阅资源 ID,供后续 READONLY_CHECK 和 INSTRUCTION_CHECK cases 使用Case: LOGIN(前置 case)
name: 登录成功并获取 Token
case_labels:
- login
- auth
- prerequisite
description: |
测试用户登录成功并获取认证令牌。
前置条件:无(这是其他 case 的前置)
environment_variables:
- name: USERNAME
type: env
value: "test@example.com"
description: 测试账号用户名
- name: PASSWORD
type: secrets
secret_ref:
workspace_key: WKS
credential_safe_key: WKS-CS-0001
credential_key: test-account-password
description: 测试账号密码;脚本里直接读同名环境变量 PASSWORD 即可
- name: AUTH_TOKEN
type: output
value: "-"
description: 登录成功后的认证令牌,供所有需要登录状态的 case 使用---
检查清单
创建或更新 case 时,确认以下内容:
- [ ]
name是否清晰描述了测试场景? - [ ]
case_labels是否包含 User Story 编号(如有)和功能模块? - [ ]
description是否包含验证点和前置条件? - [ ] 每个
environment_variable是否都有description? - [ ]
type=env的变量是否说明了数据来源? - [ ]
type=output的变量是否说明了数据用途? - [ ]
type=secrets的变量是否填了完整的secret_ref(workspace_key + credential_safe_key + credential_key),并在 description 说明凭证用途?
Testany 核心概念
实体定义
Case(平台用例)
定义:可复用的原子自动化步骤包,不等同于传统语义下的完整测试场景
属性:
case_key: 8 位大写十六进制标识符(如A1B2C3D4)name: 用例名称runtime_uuid: 执行环境 UUID(推荐 cloudprime)case_meta: case 级运行配置;后端字段名仍为trigger_method,包含 executor/path/command、environment_variablesis_private: 可见性控制workspace_keys: 私有 case 可见的工作空间列表
Pipeline(流水线)
定义:编排一个或多个 case 的执行与编排单元
属性:
pipeline_key: 格式为{WS_KEY}-{4-5位大写十六进制}(如Y2K-0601、Y2K-0001A)name: 流水线名称definition: YAML 格式的执行规则定义(Pipeline YAML)case_keys: Case keys 列表(可替代definition)- 支持依赖关系(whenPassed/whenFailed)和变量传递(relay)
Execution(执行)
定义:一次测试运行的实例
属性:
execution_id: 格式为{pipeline_key}-{5位大写十六进制}(如Y2K-0601-0000A)status: NOT_STARTED(-1), RUNNING(0), SUCCESS(1), FAILURE(2), SKIPPED(3), FAIL_AS_EXPECTED(4), CANCELLED(5), ERROR(99)
Plan(定时计划)
定义:自动化调度的执行计划
属性:
- 关联 pipeline
- Cron 表达式定义执行周期
- 可启用/禁用
Manual Trigger(手动触发)
定义:按需人工发起 pipeline 执行的触发模板
属性:
- 关联一条或多条 pipeline
- 可随时点击执行
- 每次触发都会生成一条可追踪的 Trigger Instance
Gatekeeper(门卫)
定义:由外部事件驱动的 pipeline 执行入口
属性:
- 关联 pipeline 或 pipeline group
- 对外提供 webhook 入口
- 适合 CI/CD、告警、外部系统联动触发
Workspace(工作空间)
定义:资源隔离和权限控制单元
属性:
workspace_key: 3 位大写字母数字(如Y2K)- 角色:Owner > Admin > Member > Viewer
---
可见性规则
Case / Pipeline 可见性
| 类型 | is_private | workspace_keys | 可见范围 |
|---|---|---|---|
| Global | false | [](空数组) | 全组织可见 |
| Private | true | ["WS1", "WS2"] | 仅指定工作空间可见 |
⚠️ Global / Private 的可选性受租户deployment_type约束。`type=2` 租户不允许新建 global case,也不允许 private → global。完整规则、错误码、获取deployment_type的方式见 case-visibility-policy.md。
如何选
- Agent 应先调
testany_get_tenant_config拿deployment_type,再决定默认值 deployment_type=1→ 默认 Global(无需让用户挑 workspace)deployment_type=2→ 降级为 Private + `workspace_keys`(该部署形态不允许 global)
---
工作空间角色权限
| 角色 | 权限范围 |
|---|---|
| Owner | 完全控制,包括删除工作空间、管理成员 |
| Admin | 管理资源,创建/编辑/删除 case、pipeline、plan |
| Member | 执行测试、查看结果、有限编辑 |
| Viewer | 只读访问 |
---
执行状态码
| 状态 | 值 | 含义 | 是否终态 |
|---|---|---|---|
| NOT_STARTED | -1 | 未开始/排队中 | 否 |
| RUNNING | 0 | 执行中 | 否 |
| SUCCESS | 1 | 全部通过 | 是 |
| FAILURE | 2 | 有失败 | 是 |
| SKIPPED | 3 | 跳过(仅 Case) | 是 |
| FAIL_AS_EXPECTED | 4 | 预期失败(仅 Case) | 是 |
| CANCELLED | 5 | 已取消 | 是 |
| ERROR | 99 | 系统错误 | 是 |
---
执行边界
- 平台不支持直接执行单条 case
- 真正的执行对象始终是 pipeline
- Plan / Manual Trigger / Gatekeeper 都作用于 pipeline,而不是 case
---
目录视图与标签
Labels(标签)
Testany 使用 labels 实现虚拟目录结构:
- 通过
case_labels字段管理 case 的标签 - 一个 case 可以有多个 labels,从而出现在多个目录下
- Labels 用于组织和分类测试用例
Directory View(目录视图)
目录视图是基于 labels 的层级结构:
- 每个目录对应一个 label
- Case 根据其 labels 出现在相应目录中
- 支持两种过滤模式:
- 累积视图:显示目录及所有子目录下的 cases
- 独占视图:仅显示直接属于该目录的 cases
使用场景
- 按功能分类:
login、checkout、payment - 按环境分类:
staging、production - 按团队分类:
team-a、team-b
Executor 配置详解
case_meta 的后端字段名仍为 trigger_method。这里的 trigger 指的是 case 级运行入口配置,也就是 executor 对应的 path/command;它不等于 Plan / Manual Trigger / Gatekeeper 这类 pipeline trigger。
Executor 选择规则
根据脚本语言/框架自动选择 executor:
| 脚本类型 | 默认 Executor | 判断依据 |
|---|---|---|
| Python (.py) | pyres | Python 脚本默认使用 pyres(推荐) |
| Java | maven | 有 pom.xml 则使用 maven |
| Java | gradle | 有 build.gradle 则使用 gradle |
| Postman | postman | .postman_collection.json 文件 |
| Playwright | playwright | .spec.js / .spec.ts 文件 |
注意:python 和 pyres 的区别是 pyres 提供更丰富的测试报告能力,推荐使用 pyres。
---
Postman
Executor: postman
| 字段 | 必填 | 说明 |
|---|---|---|
executor | 是 | 固定值 postman |
trigger_path | 是 | Collection JSON 在 ZIP 中的相对路径 |
{
"case_meta": {
"trigger_method": {
"executor": "postman",
"trigger_path": "my-collection.postman_collection.json"
}
}
}ZIP 结构:
my-case.zip
└── my-collection.postman_collection.json---
Python / PyRes
Executor: pyres(推荐)或 python
| 字段 | 必填 | 说明 |
|---|---|---|
executor | 是 | pyres(推荐)或 python |
trigger_command | 是 | 命令数组,空格连接执行 |
{
"case_meta": {
"trigger_method": {
"executor": "pyres",
"trigger_command": ["python", "test_api.py", "--env", "staging"]
}
}
}执行命令:python test_api.py --env staging
ZIP 结构:
my-case.zip
├── test_api.py
└── utils/
└── helpers.py高级用法 - 嵌套目录执行:
{
"trigger_command": ["cd", "tests", ";", "python", "run_all.py"]
}---
Maven
Executor: maven
| 字段 | 必填 | 说明 |
|---|---|---|
executor | 是 | 固定值 maven |
trigger_path | 是 | 测试文件路径或 ./ 表示项目根目录 |
{
"case_meta": {
"trigger_method": {
"executor": "maven",
"trigger_path": "./"
}
}
}指定测试文件:
{
"trigger_path": "src/test/java/com/testany/LoginTest.java"
}ZIP 结构:
my-case.zip
├── pom.xml
└── src/
└── test/
└── java/
└── com/testany/LoginTest.java---
Gradle
Executor: gradle
配置与 Maven 类似,区别在于项目根目录有 build.gradle 而非 pom.xml。
{
"case_meta": {
"trigger_method": {
"executor": "gradle",
"trigger_path": "./"
}
}
}---
Playwright
Executor: playwright
| 字段 | 必填 | 说明 |
|---|---|---|
executor | 是 | 固定值 playwright |
trigger_path | 是 | spec 文件相对路径 |
playwright_config_path | 否 | 配置文件路径,省略则自动检测 |
{
"case_meta": {
"trigger_method": {
"executor": "playwright",
"trigger_path": "tests/e2e/login.spec.js",
"playwright_config_path": "playwright.config.js"
}
}
}必需文件:
package.jsonplaywright.config.js(或在playwright_config_path指定)
ZIP 结构:
my-case.zip
├── package.json
├── playwright.config.js
└── tests/
└── e2e/
└── login.spec.js---
环境变量
限制
- 每个 case 最多 16 组 环境变量
name必须遵循 POSIX.1-2017 标准:仅大写字母、数字、下划线(如API_URL、MAX_RETRY_COUNT)name在同一 case 内必须唯一(不区分 type)- 每条变量按
type决定填value还是secret_ref(见下表)
类型
| type | 用途 | 如何填 |
|---|---|---|
env(默认) | 普通环境变量、relay 输入 | 填 value(必填、非空) |
output | 输出变量,供 pipeline 中其他 case relay 消费 | 填 value(运行时由脚本写入,初始可用 "-" 占位) |
secrets | 引用 workspace 的 Credential Safe 条目 | 填 secret_ref(禁止填 value);脚本里直接读同名环境变量即可 |
`secret_ref` 结构:{ workspace_key, credential_safe_key, credential_key },三个字段都必填。
`secrets` 行的只读字段:读回 case 时每条 secrets 行附带 status(valid / blocked / invalid)和 status_reasons[];非 valid 要向用户说明原因(常见:owner_access_not_satisfied、visibility_not_satisfied、target_not_found_or_unresolvable、secret_ref_malformed)。写入时不要传这两个字段。
查询 credential_safe_key / credential_key
如果用户没有现成的 safe_key / credential_key,按顺序用两个 MCP 工具解析:
1. `testany_list_credential_safes`(入参 workspace_key + runtime_uuid)→ 返回该 workspace 可见的 Credential Safes 2. 从返回列表中取目标 safe 的 key 字段作为 credential_safe_key 3. `testany_list_credential_keys`(入参 credential_safe_key + runtime_uuid)→ 返回该 safe 下的所有 credential 4. 取目标 credential 的 key 字段(不是 `name`)作为 credential_key
关键约束:
- 两个工具都需要
runtime_uuid,且必须与 case 的 `runtime_uuid` 一致——TSSM 是按 runtime 部署的,不同 runtime 看到的 safe 列表不同 - 两个工具都不直接返回数据,返回的是
{sign, url, curlCommand};agent 必须执行返回的curlCommand才能拿到列表(MCP 与 TSSM 运行在不同集群) secret_ref.credential_safe_key/credential_key必须填返回中的 `key`,不要用name(name仅是展示名,可重复)
返回字段速查:
| 工具 | 返回每项的关键字段 |
|---|---|
testany_list_credential_safes | key(给 credential_safe_key 用)、name、type(底层 KMS,如 azure-key-vault)、workspace |
testany_list_credential_keys | key(给 credential_key 用)、name、safe_key、type、env、description、expire_date、labels |
故障处理:
- curl 返回 HTTP 401 且 body 为空 → 签名时序/缓存问题。重新调用同一个 MCP 工具拿新签名再试,通常立刻成功
- curl TLS 握手失败(exit 35、connection reset)→ 当前环境到该 runtime 的 TSSM 网关不可达;若用户允许切换 runtime,换一个 trusted runtime 再试,否则如实报告
端到端示例:
# 1) 列 workspace 下的 safe
testany_list_credential_safes(workspace_key="MCP", runtime_uuid="81c91231-...")
→ 执行返回的 curlCommand → [{"key":"MCP-CS-0B89", "name":"BOYI-Azure-Keyvault", "type":"azure-key-vault", ...}]
# 2) 列 safe 内的 credential
testany_list_credential_keys(credential_safe_key="MCP-CS-0B89", runtime_uuid="81c91231-...")
→ 执行返回的 curlCommand → [{"key":"boyi-github-token", "name":"my-secret", ...}, ...]
# 3) 填入 case_meta.environment_variables 的 secret_ref
{
"name": "GITHUB_TOKEN",
"type": "secrets",
"secret_ref": {
"workspace_key": "MCP",
"credential_safe_key": "MCP-CS-0B89",
"credential_key": "boyi-github-token"
},
"description": "GitHub API 访问凭证"
}配置示例
{
"case_meta": {
"environment_variables": [
{ "name": "API_URL", "type": "env", "value": "https://api.example.com" },
{
"name": "API_KEY",
"type": "secrets",
"secret_ref": {
"workspace_key": "WKS",
"credential_safe_key": "WKS-CS-0001",
"credential_key": "prod-api-key"
}
},
{ "name": "TOKEN", "type": "output", "value": "-" }
]
}
}