关于 run-test-plan
用于按顺序执行 YAML 测试计划的技能,适合验证应用的开发者。它会先检查环境与健康状态,收集测试证据,并在首次失败时停止并生成调试报告。
主要功能
- 01解析并验证 YAML 计划
- 02运行环境准备与健康检查
- 03按顺序执行测试
- 04收集命令及浏览器证据
- 05失败即停并生成调试信息
适用场景
- 01执行项目文档中的测试计划
- 02跳过已完成的准备步骤重新测试
- 03依据证据诊断首个失败项
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ existential-birds/ beagle --skill run-test-plan安装后在 Claude Code 中输入/run-test-plan确认已加载。
详细介绍
运行测试计划
执行 YAML 测试计划,运行设置命令、健康检查,并按顺序执行每项测试。首次失败时停止,并提供丰富的调试输出。
前提条件
- agent-browser CLI:浏览器测试要求
agent-browser命令行工具可通过PATH使用
参数
--plan <path>:测试计划路径(默认:docs/testing/test-plan.yaml)--skip-setup:跳过设置命令和健康检查(用于失败后重新运行)
第 1 步:解析测试计划
读取并验证测试计划:
# Resolve plan path from --plan (default shown)
PLAN_PATH="${PLAN_PATH:-docs/testing/test-plan.yaml}"
# Check file exists
ls "$PLAN_PATH" || { echo "Error: Test plan not found: $PLAN_PATH"; exit 1; }
# Validate YAML
python3 -c "import yaml; yaml.safe_load(open('$PLAN_PATH'))" || { echo "Error: Invalid YAML: $PLAN_PATH"; exit 1; }
从 YAML 中提取:
setup.commands:设置命令列表setup.health_checks:要轮询的 URL 列表tests:测试用例数组
第 2 步:运行设置(除非使用 --skip-setup)
2a. 检查前提条件
如果存在 setup.prerequisites,验证每一项:
# For each prerequisite in setup.prerequisites
<prerequisite.check> || { echo "Prerequisite not met: <prerequisite.name>"; exit 1; }
2b. 设置环境变量
如果存在 setup.env,导出其中的每个变量。使用 ${VAR} 语法的变量应从当前环境中解析:
# For each key/value in setup.env
export <key>="<value>"
2c. 构建
如果存在 setup.build,按顺序执行构建命令:
# For each command in setup.build
<command> || { echo "Build failed: <command>"; exit 1; }
2d. 启动服务
如果存在 setup.services,启动长时间运行的进程并等待健康检查:
# For each service in setup.services
nohup <service.command> > .beagle/service-<index>.log 2>&1 &
echo $! > .beagle/service-<index>.pid
对于每个包含 health_check 的服务,轮询直至就绪:
timeout=<service.health_check.timeout or 30>
url=<service.health_check.url>
elapsed=0
while [ $elapsed -lt $timeout ]; do
if curl -s -o /dev/null -w "%{http_code}" "$url" | grep -qE "^(200|301|302)"; then
echo "✓ Health check passed: $url"
break
fi
sleep 2
elapsed=$((elapsed + 2))
done
if [ $elapsed -ge $timeout ]; then
echo "✗ Health check timeout: $url"
exit 1
fi
2e. 旧版设置格式
如果计划使用较旧的扁平格式(setup.commands + setup.health_checks,而非 prerequisites/build/services),则回退到按顺序执行 setup.commands,并像以前一样轮询 setup.health_checks。
第 3 步:门禁 — 测试开始前确保设置就绪
在以下每项可检查的条件都满足之前,不要开始 第 4 步:
- 计划加载:
--plan指定的文件(默认docs/testing/test-plan.yaml)存在且可解析为 YAML(执行与第 1 步相同的检查)。 - 设置分支:
- 如果未使用
--skip-setup:所有存在的setup.prerequisites检查均以状态码 0 退出;所有setup.build命令均成功;每个服务的health_check均在超时前返回 HTTP 200、301 或 302;或者旧版setup.health_checks在执行setup.commands后通过。 - 如果使用了
--skip-setup:在 TC-01 之前,确认计划仍需要的各项服务均在运行——至少对测试所依赖的setup.health_checks中每个 URL,或setup.services[].health_check.url中的每个 URL,成功执行一次curl(或等效操作)。
- 如果未使用
- 证据路径:
mkdir -p docs/testing/evidence执行成功,且该目录存在。
如果任一门禁条件未通过,则停止,修复设置或标志,不要执行测试。
第 4 步:按顺序执行测试
对于计划中的每项测试:
4a. 记录测试开始
## Running: TC-XX - <test.name>
Context: <test.context>
4b. 执行步骤
对于 test.steps 中的每个步骤,判断其类型并相应执行:
Shell 命令(run: 步骤):
这是最常见的步骤类型。通过 Bash 执行命令,并捕获标准输出、标准错误和退出码:
# Execute the command, capture output and exit code
<command> 2>&1
echo "EXIT_CODE: $?"
捕获所有输出,以便在第 4c 步中评估。Shell 步骤涵盖:
- CLI 二进制文件调用(例如,
./target/debug/myapp status --all) - 数据库查询(例如,
psql "${DATABASE_URL}" -c "SELECT ...") - 文件检查(例如,
ls -la /path/to/expected/output) - 进程生命周期检查(例如,
timeout 5 ./myapp 2>&1 || true) - 人们会在终端中输入的任何其他命令
curl 操作(action: curl 步骤):
curl -X <method> \
-H "Content-Type: application/json" \
<additional headers> \
-d '<body>' \
"<url>" \
-o response.json \
-w "%{http_code}" > status_code.txt
# Capture response for evaluation
cat response.json
cat status_code.txt
agent-browser CLI 操作:
以 agent-browser 开头的步骤是浏览器自动化命令:
# Navigate
agent-browser open <url>
# Snapshot interactive elements (always do before interacting)
agent-browser snapshot -i
# Interact using refs from snapshot output (@e1, @e2, etc.)
agent-browser fill @<ref> "<value>"
agent-browser click @<ref>
# Wait for conditions
agent-browser wait --url "<pattern>"
agent-browser wait --text "<text>"
agent-browser wait --load networkidle
# Capture evidence
agent-browser screenshot docs/testing/evidence/<test.id>.png
重要: 与元素交互之前,始终先运行 agent-browser snapshot -i,以获取有效的 refs;导航后或 DOM 发生重大变化后,重新获取快照。
将屏幕截图保存到 docs/testing/evidence/<test.id>.png
4c. 评估结果
门槛——判定 PASS/FAIL 前先确认产物:
- **
run:步骤:**已捕获标准输出和标准错误;已记录退出代码(例如EXIT_CODE:行或等效内容)。 - **
action: curl步骤:**已将响应正文和 HTTP 状态码捕获到已知路径(例如response.json、status_code.txt,或计划指定的路径)。 - **agent-browser 步骤:**每次导航或 DOM 变更后,在断言前都存在新的
agent-browser snapshot -i;若测试记录证据,则已创建截图文件路径,或明确记录了失败。
然后,使用 Agent 推理将实际结果与 test.expected 进行比较:
- 阅读预期行为说明
- 将实际响应/截图与预期进行比较
- 判定 PASS 或 FAIL
4d. PASS 时
✓ TC-XX PASSED: <test.name>
继续下一个测试。
4e. FAIL 时
立即停止。转到第 6 步。
第 5 步:所有测试均通过时
## Test Results: ALL PASSED
| ID | Name | Result |
|----|------|--------|
| TC-01 | <name> | ✓ PASS |
| TC-02 | <name> | ✓ PASS |
| ... | ... | ... |
**Total:** N/N tests passed
### Evidence
Screenshots saved to `docs/testing/evidence/`
### Cleanup
Stopping background services...
清理:
# Kill background services
for pidfile in .beagle/service-*.pid .beagle/dev-server.pid; do
if [ -f "$pidfile" ]; then
kill $(cat "$pidfile") 2>/dev/null
rm "$pidfile"
fi
done
第 6 步:失败时——生成调试提示词
测试失败时,生成详尽的调试输出:
6a. 收集上下文
# Get changed files relevant to the failure
git diff --name-only $(git merge-base HEAD origin/main)..HEAD
# Get recent changes in files mentioned in test.context
git diff $(git merge-base HEAD origin/main)..HEAD -- <relevant_files>
6b. 输出调试报告
## Test Failure: TC-XX - <test.name>
### What Failed
**Test:** <test.name>
**Expected:**
<test.expected>
**Actual:**
<Describe what actually happened - response code, error message, screenshot description>
### Relevant Changes in This PR
<For each file mentioned in test.context or related to the failure:>
- `<file>` (lines X-Y) - <brief description of changes>
### Evidence
<If screenshot exists:>
- Screenshot: `docs/testing/evidence/<test.id>.png`
<If API response:>
- Status code: <code>
- Response body:
```json
<response>
错误详情
<如果响应或日志中有错误消息:>
<error message>
建议的调查方向
<根据错误,建议检查 2–3 项具体内容:>
- <根据错误类型首先要检查的内容>
- <与已更改文件相关的第二项内容>
- <有关环境/设置的第三项内容>
调试会话提示词
复制以下内容以启动新的 Agent 会话:
我正在调试分支 <branch> 中的测试失败。
测试: <test.name> 错误: <简要错误描述>
<概述测试的检查内容以及出现的问题>
相关文件: <列出与此测试相关的已更改文件>
请帮我调查 <具体失败原因>。
### 6c. Preserve Evidence
```bash
# Ensure evidence directory exists
mkdir -p docs/testing/evidence
# Save failure context
cat > docs/testing/evidence/<test.id>-failure.md << 'EOF'
# Failure Report: <test.id>
<Full debug report content>
EOF
6d. 清理并退出
# Kill background services
for pidfile in .beagle/service-*.pid .beagle/dev-server.pid; do
if [ -f "$pidfile" ]; then
kill $(cat "$pidfile") 2>/dev/null
rm "$pidfile"
fi
done
测试结果汇总表
始终输出汇总表以显示进度:
## Test Results
| ID | Name | Result |
|----|------|--------|
| TC-01 | <name> | ✓ PASS |
| TC-02 | <name> | ✗ FAIL |
| TC-03 | <name> | - SKIP |
**Passed:** 1/3
**Failed:** TC-02
失败后未执行的测试标记为 SKIP。
验证
完成前:
# Verify evidence directory exists
ls -la docs/testing/evidence/
# List captured evidence
ls docs/testing/evidence/*.png docs/testing/evidence/*.md 2>/dev/null
通过条件(以下条件必须全部满足,才能判定本次运行完成):
ls -la docs/testing/evidence/退出码为 0(目录存在)。- 每个已运行的测试都有明确的 PASS 或 FAIL 结果(不能只凭“感觉没问题”)。
- 如果有任何测试失败:存在失败产物(
docs/testing/evidence/<test.id>-failure.md或等效文件),或者已输出包含预期结果与实际结果的调试报告。 - 已执行清理:没有指向你启动的运行中进程的过期
.beagle/service-*.pid,除非计划要求将其保留运行。
验证清单:
- 设置命令已成功执行(或使用
--skip-setup,并已确认依赖服务正在运行) - 执行测试前健康检查已通过(第 3 步门槛)
- 每个已执行的测试都记录了结果
- 证据已保存在
docs/testing/evidence/ - 失败时:调试提示词包含预期结果与实际结果
- 失败时:已列出相关 PR 更改
- 已清理后台进程
门槛(按顺序)
- **计划有效:**YAML 可解析;当前分支所需的键(
setup/tests)均存在。 - **设置正常:**TC-01 开始前已满足第 3 步的通过条件。
- **每项测试的产物:**判定 PASS 前已满足第 4c 节的门槛。
- **失败即停止:**首次失败 → 第 6 步;后续测试在汇总表中标记为 SKIP。
- **清理:**已执行第 5 步或第 6d 节,以释放本次运行启动的后台进程 PID。
规则
- 首次测试失败时立即停止(不要继续其他测试)
- 始终捕获证据(截图、响应)
- 尽可能在调试提示词中包含文件和行号引用
- 修复问题后使用
--skip-setup标志重新运行 - 切勿硬编码密钥——使用环境变量
- 即使失败,也要清理后台进程
- 保留失败证据以供调试
- 让调试提示词可直接复制粘贴到新会话中使用