testany-debug
$
npx mdskill add TestAny-io/testany-agent-skills/testany-debug分析 Testany 测试失败原因,排查问题根因。
SKILL.md
.github/skills/testany-debugView on GitHub ↗
---
name: testany-debug
description: 分析 Testany 测试失败原因 - 排查问题、查看日志、定位根因
---
# Testany 故障诊断
分析 Testany 测试失败原因,排查问题根因。
用户输入: $ARGUMENTS
## 职责范围
- 分析测试执行失败的原因
- 获取和解读执行日志
- 识别常见问题模式
- 提供修复建议
## 核心知识
### 失败类型分类
| 类型 | 特征 | 常见原因 |
|------|------|---------|
| **Assertion** | 断言失败 | 预期值与实际值不符 |
| **Timeout** | 执行超时 | 接口响应慢、死循环 |
| **Error** | 运行时错误 | 代码异常、依赖缺失 |
| **Infrastructure** | 基础设施问题 | 网络不通、服务不可用 |
| **Scheduler / Queue** | 调度/排队问题 | 并发槽位占满、execution 排队、并行未生效 |
### 日志获取流程
按日志来源分两条路径:
**Execution 日志(pipeline 真实运行产物)**:
```
1. testany_get_execution → 获取执行概览
2. testany_get_execution_case → 获取失败 case 详情
3. testany_log_sign → 获取日志签名(返回 curlCommand)
4. 验证 curlCommand 安全性后执行获取日志
```
**Dry run 日志(case 自身验证产物)**:
```
1. testany_get_dry_run_result → 确认 dry_run_status 进入终态(>=1)且 dry_run_result.sign 已产出
2. testany_get_dry_run_log → 拼出 logUrl + curlCommand(同样基于 sign)
3. 验证 curlCommand 安全性后执行获取日志
```
注意:execution 和 dry run 共用同一套日志域 (`<runtime_uuid>.tr.<domain>/api/v2/logproxy/internal/view`) 和同一套 status 数值(1=SUCCESS、0=RUNNING、-1=NOT_STARTED),下面的安全验证规则两条路径都适用。
### curlCommand 安全验证(重要)
`testany_log_sign` / `testany_get_dry_run_log` 返回的 `curlCommand` 在执行前**必须验证**:
1. **检查域名**:URL 必须是 Testany 可信域名
- 允许:`*.testany.io`、`*.testany.com.cn`
- 拒绝:其他任何域名
2. **检查协议**:必须是 HTTPS
- 允许:`https://`
- 拒绝:`http://`、其他协议
3. **检查参数**:不应包含危险参数
- 禁止:`-o`(写文件)、`|`(管道)、`;`(命令链)、`$(`(命令替换)
**验证示例**:
```bash
# 从 curlCommand 提取 URL
URL=$(echo "$CURL_COMMAND" | grep -oP 'https://[^\s"]+')
# 验证域名
if [[ "$URL" =~ ^https://(.*\.)?testany\.(io|com\.cn)/ ]]; then
# 安全,可以执行
eval "$CURL_COMMAND"
else
# 不安全,拒绝执行
echo "警告:URL 域名不在可信列表中,拒绝执行"
fi
```
## 诊断工作流
1. **获取执行信息**:`testany_get_execution`
2. **定位失败 case**:从执行详情中找到失败的 case
3. **获取日志签名**:`testany_log_sign(executionKey, caseIndex)`
4. **安全验证**:检查返回的 curlCommand 域名和参数
5. **获取日志**:验证通过后执行 curlCommand
6. **分析日志**:识别错误类型和位置
7. **提供建议**:给出修复方向
## 常见问题速查
| 症状 | 可能原因 | 排查步骤 |
|------|---------|---------|
| Case 创建后无法执行 | runtime 未配置 | 检查 `runtime_uuid` |
| Relay 变量未传递 | type 配置错误 | 源 case 需 `type='output'`,目标需 `type='env'` |
| Pipeline 执行卡住 | 依赖 case 失败 | 检查 `whenPassed` 依赖的 case 状态 |
| 脚本执行报错 | executor 配置不匹配 | 检查 `trigger_path` 或 `trigger_command` |
| 超时 | 接口响应慢 | 检查被测服务状态,增加超时配置 |
| YAML 是并行但执行表现串行 | 平台调度限流 | **优先检查队列状态**(见下方调度诊断) |
| Execution 长时间 NOT_STARTED | 并发槽位被占满 | 检查 workspace 队列状态 |
| 多个 execution 互相排队 | queue.limit 限制 | 检查 claimed/pending 列表 |
## 调度 / 队列诊断(Scheduler / Queue)
**当用户报告"并行未生效"或"execution 卡住不跑"时,必须优先走这条诊断路径,再去排查 YAML 和 relay。**
### 核心概念
Testany 使用 **workspace 级并发槽位**控制 execution 并行度:
| 概念 | 含义 |
|------|------|
| `limit` | workspace 的并发上限(Community=2, Paid=4, Enterprise=8,可调) |
| `claimed` | 当前正在执行的 execution 列表(已占据槽位) |
| `pending` | 排队等待槽位的 execution 列表 |
| `trigger_group` | 触发源标识(`M-`=手动触发,`G-`=Gatekeeper,Plan key=计划触发) |
### 诊断流程
```
1. testany_get_workspace_execution_status → 获取 {limit, claimed, pending}
2. 判断:
- claimed 数量 = limit?→ 槽位已满,pending 中的 execution 必须等
- claimed 中有长时间运行的旧 execution?→ 旧执行占住了槽位
- pending 列表里有你关注的 execution?→ 它在排队,不是 YAML 问题
3. 如果槽位未满但 case 仍然串行:
- 检查 pipeline YAML 版本:rule/v1.2 不支持 case 级并行,只有 rule/v1.3 支持
- 检查 workspace 是否启用了并行执行功能
- 比对 case 的 start_time / finish_time:如果 case 间有明显间隔(>数秒),说明被平台串行调度
4. 如果是 fan-out pipeline(无 whenPassed/whenFailed 依赖)仍然串行:
- 大概率是 effectiveConcurrency=1 或 workspace 并行未开启
```
### 关键字段获取
| 要看的信息 | 获取方式 |
|-----------|---------|
| workspace 队列状态 | `testany_get_workspace_execution_status` → limit/claimed/pending |
| 单个 execution 详情 | `testany_get_execution` → status, start_time, trigger_group |
| case 级时间线 | `testany_get_execution` → cases[].start_time / finish_time |
| 确认 pipeline 版本 | 查看 pipeline YAML 的 `rule/v1.3` 或 `rule/v1.2` |
### 真实案例:fan-out pipeline 表现串行
**场景**:用户编排了一条 fan-out pipeline,token case → 25 个 Postman shard(YAML 无依赖,理论上并行),但实际串行执行。
**排查路径**:
1. `testany_get_workspace_execution_status` → 发现 `limit=1`,`claimed` 中有 1 个旧 execution
2. 说明 workspace 并发上限为 1,所有 execution 都串行排队
3. 进一步确认:`claimed` 中的旧 execution 完成后,pending 中的 execution 才逐一开始
4. 同一 execution 内部的 case 启动时间也呈串行——因为 case 级并行同样受 `effectiveConcurrency` 限制
**结论**:问题不在 YAML,不在 relay,不在 case 依赖——是平台调度层的并发限制。
**解决方向**:
- 联系管理员调整 workspace 的 `concurrency_limit`
- 确认 workspace 已启用并行执行功能(rule/v1.3 + allowlist)
- 如果是 Community 版,默认并发=2,无法通过 YAML 优化绕过
## 返回格式
诊断完成后,向用户汇报:
- 失败原因分类(Assertion/Timeout/Error/Infrastructure)
- 具体错误信息
- 问题定位(哪个 case、哪一步)
- 修复建议
- 日志查看链接(如需要)
## 参考文档
详细概念请参考:
- [核心概念](../testany-guide/references/concepts.md)
More from TestAny-io/testany-agent-skills
- api-reviewerAPI contract review, 接口契约评审。Use when: PRD 完成后、HLD/LLD/实现前需要审查 OpenAPI/AsyncAPI/GraphQL/gRPC/WebSocket/SSE/Webhook/SDK/文件格式/IPC-CLI 契约。
- api-writerWrite API contract, 写接口契约。Use when: PRD 完成后、HLD 之前需要定义 OpenAPI/AsyncAPI/GraphQL/gRPC/WebSocket/SSE/Webhook/SDK/文件格式规范。
- brd-interviewerBRD interview, 业务需求访谈。Use when: 需要将模糊的业务想法梳理成 BRD、"帮我梳理业务需求"、"老板说要做 XXX"、"这个需求不太清楚"、"写 BRD"。
- guardrails-reviewerReview Project Guardrails, 工程规范评审。Use when: Guardrails 创建或更新后需要作为项目级治理基线做准出,检查触发判定、生成模式、事实标准、下游工作流钩子与规则可执行性。
- guardrails-writerWrite Project Guardrails, 写工程规范。Use when: 需要创建或更新项目级 Guardrails 基线,明确跨模块/跨团队的默认约束、更新触发条件与下游工作流钩子;适用于项目启动、架构/平台/合规变化、事故复盘、重复评审问题固化。
- guideGuide, workflow guide, 流程导航、我该用哪个 skill、下一步做什么。Use when: 需要扫描当前项目已有文档和准出状态,判断 testany-eng 主流程所处阶段,并推荐下一步最合适的 skill;当 Test Spec 已具备下游 handoff 条件时,也可推荐进入 testany-bot 自动化落地分支。
- hld-reviewerHLD review, High-Level Design review, 技术方案评审。Use when: HLD 完成后、进入 LLD/实现前需要审查技术设计、检测 PRD→HLD 漂移。
- hld-writerWrite HLD, High-Level Design, 写技术设计文档。Use when: PRD 和 API Contract 完成后需要做系统架构设计、技术选型、制定技术方案。
- lld-reviewerLLD review, Low-Level Design review, 详细设计评审。Use when: 实现前需要审查 LLD 与 PRD/HLD/API Contract/Guardrails 的一致性。
- lld-writerWrite LLD, Low-Level Design, 写详细设计。Use when: PRD/HLD/API Contract 完成后需要写模块设计、接口设计、实现级技术方案。