排查一次失败的运行
一次运行停在了某处,你不知道为什么。按这个顺序来——从最省力到最侵入,大多数失败在前两步就能定位。
1. 读代码,不读句子
运行会报出一个稳定的错误码。在推测之前先去错误码里查它。最容易造成混淆的三个:
| 错误码 | 它实际意味着什么 |
|---|---|
TRANSITION_NOT_FOUND | 某个节点返回了一个没有接线的 route。节点是好的;你的图上有个洞 |
MAX_NODE_EXECUTIONS_EXCEEDED | 某个循环执行的节点数超过了护栏。什么都没坏——是上限太低,或者循环不退出 |
MAX_CONSECUTIVE_FAILURES_EXCEEDED | 有东西反复失败且中间没有任何成功。检测的"未找到"不会导致这个——去找一个动作节点 |
2. 找到最后运行的那个节点
日志会点出它。那个节点是你的起点——但要小心该怪哪个节点:
- 如果最后那个是检测节点,它往往正是尽了职。什么都没找到的
Find Image报告 statussuccess并路由到 Failure。如果 Failure 没接线,运行就在这个检测节点上以TRANSITION_NOT_FOUND死掉——而检测节点不是 bug。见status 与 route。 - 如果最后那个是动作节点,就去看那一刻屏幕上是什么。那是第 3 步。
3. 打开 Run Evidence 并复现
Run Evidence 在流程开始前、每个 UI 动作之后、以及完成时采集截图。它是产品里最有用的排错工具,因为它把"猜屏幕上有什么"换成了"看屏幕上有什么"。
- 在实例仪表盘上设置 Evidence Folder…。
- 只在一个实例上打开 Run Evidence——不是整个池子。
- 重跑,然后从 View Logs / Activity Logs 打开图片。
看失败动作之前那一帧。十次里有九次,下面某一条成立:
- 应用不在流程假定的那个界面上。
- 有个弹窗盖住了目标。
- 动作在上一个界面动画还没走完时就发出了——那一帧能证明。
Evidence 每个动作写一张图。长流程开着 evidence 会产生非常大的目录。诊断时开,运维运行时关。
4. 用 Debug Mode 逐步走那个判断
如果问题是*"它为什么走了那条分支"*,别再读了——看着它走。
右键一个节点 → Add debug breakpoint,然后打开 Debug Mode。运行会在断点处暂停,你一个节点一个节点地推进,看 Execution 面板报告 Current Node、Elapsed、Duration,以及对 OCR 节点报 Extracted variables。
在你不信任的那部分周围设断点。Debug Mode 不设断点会在每个节点暂停——那是有意的,但在长流程上慢得难受。
5. 用 Test Node 把节点孤立出来
一旦怀疑某个具体节点,就单独测它。Test Node 只针对已附加实例运行那一个节点,Test Result 显示发生了什么。
感知类的问题在这里用数字而不是意见来定案:
| 节点 | Test Node 告诉你 |
|---|---|
| Find Image | 真实置信度。如果你最好的分数是 0.62 而阈值是 0.88,那问题在模板——不在阈值 |
| Read Text | 原始 OCR 和提取出的变量。如果原始文本就是错的,那是区域或内容类型错了——不是你 的模式 |
| Check Region | 实测值对比预期与容差 |
6. 当 Test Node 过了而流程仍然失败
这是最经典的情形,通常有两个原因:
该节点的来源不在已执行路径的上游。 一个坐标来源指向 Find Image 节点的 Click,只有当那个 Find Image 真的在这条路径上跑过才成立。复制粘贴来的节点老是撞上这个——设置被复制了,关系没有。错误码是 COORDINATE_SOURCE_UNAVAILABLE。
一次验证读到了动作前的画面。 动作发出了,验证在屏幕改变之前就跑了,于是读到了旧状态。在两者之间加一个沉降 Wait——并给它写上 Reason,这样半年后你还知道那个数字为什么存在。
Test Node 孤立地跑它;Test Flow 在上下文中跑它。当两者结论不一致,上下文就是那个 bug。
7. 按需复现
一个你无法触发的间歇性失败,就是一个你无法修的失败。用 Practice App 强制出确切状态:
dashboard.html?popup=1—— 弹窗在dashboard.html—— 不在?gold=0—— 走"不够"那条分支?gap=40—— 另一个滑动距离
把状态固定下来,就把"它有时会失败"变成了一个你能跑两遍的测试。
检查清单
- 在错误码里查过错误码
- 找出了最后运行的节点——并且问过它是元凶还是只是现场
- 检查过失败的 route 是不是压根没接线
- 看过失败之前那一帧 Run Evidence
- 对可疑节点跑过 Test Node 并读了真实数字
- 确认过该节点的来源在它实际走的那条路径的上游
- 用固定的 Practice App 数值复现过