AI 测试提效丨从失败排查到自动修复,分享我的Playwright+Skill UI自动化测试失败诊断提效方案!

大家好,我是狂师。

上一篇我们把「跑测试」交给了 AI。环境自动检测、失败证据自动保全、报告自动产出,执行这一环确实痛快了。

但打开报告,几十条脚本用例红着,耗时费力的事这才真正开始。

这条为什么挂?是环境、是脚本、是数据,还是真有 bug?

我见过太多人面对一片红条的反应,先重跑一遍。过了就当无事发生,没过就对着报错信息开始猜。猜环境、猜数据、猜前端改了东西,一猜半个小时起步。

一、开头说两句

这个系列一直在做一件事,用 Agent Skill 把 UI 自动化测试的各个环节逐个自动化。

上一篇的 ui-test-executor 解决了「跑」的问题,顺带留下了六类失败证据,截图、录屏、Trace、日志、页面源码、网络请求,全部归档得整整齐齐。

6 类 Artifact(仅失败时采集):

类型 触发 路径
screenshots setup/call 失败 artifacts/screenshots/
page-source setup/call 失败 artifacts/page-source/
console-logs setup/call 失败 5 段合并:Page Errors / Console / Network / Performance
videos call 失败 artifacts/pytest-raw/<slug>/video.webm
traces call 失败 artifacts/pytest-raw/<slug>/trace.zip
har 等价 失败 写入 console-logs 的 ## Network

这些证据拿在手,接下来的问题变成了「为什么挂」。

失败分析是 UI 自动化里最吃经验、也最重复的环节。

看截图、翻日志、读堆栈、判断原因、动手修复,每一步都有章法可循。而凡是「有章法可循」的事,就值得固化成 Skill 交给 AI。

所以这一环,我做了 ui-failure-diagnoser,一个失败用例智能诊断与自动修复的 Skill。它接过上一篇留下的失败档案,把「分析原因、定位根因、执行修复」这条链全部自动化。

本篇就聚焦这个 Skill,从它面对的问题讲起,到它怎么解决,再到实战跑一遍。

二、传统失败诊断方式存在什么问题

把失败分析这件事,拆开来说,问题往往集中在几个主要地方。

1、失败原因,全靠人猜。

一条用例挂了,对着满屏英文堆栈猜原因。猜是环境,重启服务试试;猜是数据,换个账号试试;猜是前端改了,翻翻代码提交记录。猜对了算运气好,猜错了一下午就搭进去。

2、误判的代价,比不判还大。

环境问题被当成 bug 提了缺陷单,开发看完退回来,一句「环境没配好」让你白写半天报告。更隐蔽的是反过来,真 bug 被当成偶发失败重跑两遍跑过了,缺陷就这么漏到线上。方向判错,后面全白干。

3、证据在手,不会关联。

上一篇留下的截图、日志、Trace 都在,但人排查时很少真去挨个打开。截图看一眼,日志翻两行,Trace 根本不会开。单条证据孤零零躺着,线索之间串不起来。

4、一个失败查半天,一片失败直接躺平。

对于很多新手来说,一条用例排查半小时,十条就是一下午。CI 红一片的时候,最常听到的建议是「先重跑一遍看看」,没人真有精力逐条分析。

5、修好了,坑没记住。

这次踩的坑,下个项目原样再踩一遍。没有失败分类、没有根因统计,说不出团队里哪类失败最频繁、哪个模块最脆弱,改进无从下手。

6、定位到了,修复还是人肉。

原因查明白了,改 locator、调 timeout、清脏数据,还是得自己一行行动手。诊断占两小时,修复又占一小时。

这几件事有个共同点。判断有规则可依,排查有路径可循,修复有套路可抄。全是 AI 擅长的活。

那能不能让 AI 把「失败诊断」这一步也接管了?

答案是,可以。而且它不只是给建议,还能直接把问题修复都做了。

三、ui-failure-diagnoser Skill 技能介绍

简单来说,ui-failure-diagnoser 是一个专门负责失败用例诊断与自动修复的 Agent Skill。

它的输入正好是上一篇 ui-test-executor 的产出,测试执行结果加六类失败证据;输出是一份修复报告,外加已经改好的代码和清理干净的数据。

输入

  • Skill 2 输出的 ui_execution_results.json
  • 失败现场截图
  • 浏览器控制台日志
  • 网络请求记录(HAR 文件)

处理逻辑

  1. 截图智能分析:AI 分析失败时刻的页面截图,识别元素是否存在、是否被遮挡、是否错位;
  2. 日志自动解析:提取浏览器控制台报错、网络请求异常、JS 错误堆栈;
  3. 失败模式匹配:基于规则库和历史数据,分类失败类型(环境/定位/等待/数据/脚本/产品缺陷);
  4. 根因深度定位
    • 环境问题:浏览器驱动不匹配、分辨率异常、服务未启动;
    • 定位问题:元素定位失效、DOM 结构变更、动态 ID 变化;
    • 等待问题:页面加载超时、异步数据未返回、动画未结束;
    • 数据问题:测试数据被污染、数据过期、数据依赖缺失;
    • 脚本问题:操作逻辑错误、断言过严、参数构造错误;
    • 产品缺陷:前端 JS 报错、接口异常、页面样式错乱、功能逻辑错误;
  5. 修复建议生成:针对每类失败,生成具体的修复建议(更新定位策略、补充等待逻辑、调整断言等);

输出

  • 失败用例修复后脚本
  • 失败修复报告(含具体代码/失败原因分析/修改策略)

适用场景:

  • 测试失败后自动分析失败原因、分类失败类型
  • 诊断 UI 测试失败根因(环境、定位器、超时、数据、脚本、Bug)
  • 元素找不到、页面渲染慢、iframe 切换缺失等自动修复
  • 已知 Bug 注入 xfail/flaky marker,不掩盖真实缺陷
  • 批量诊断并修复失败用例

它的整个设计遵循两条原则。

先分类,再动手。 不上来就猜,先按判定信号把失败分成六类,每一类对应一套明确的修复策略。诊断的章法,全部固化成规则。

能修的修,不能修的标出来。 这个 Skill 有一条硬约束,永远不修改测试用例的断言和业务语义

可以改页面对象层的定位器,可以调超时参数,可以在配置里打标记,但测试想验证什么,它一个字都不碰。这条底线守住,修复才敢放心让它做。而且每一个动作都有审计日志,每一处修改都有备份。

落到流程上,它固化成一套失败诊断五步流程。

失败加载 → 分类判定 → 根因定位 → 自动修复 → 验证报告

对着前面这几个问题,一步一步看它是怎么拆的。

1. 失败自动分类

六类失败,每一类都有明确的判定信号。比如:

类型 判定信号 处理
ENV_ERROR 浏览器/包未装、端口占用 ✅ 自动 playwright install / pip install / lsof
LOCATOR_ERROR Timeout + locator 在 page-source 不存在 ✅ AST 修复 + pages.yaml 对比 + 语义推断
TIMEOUT_ERROR Timeout + locator 存在(渲染慢) ✅ AST rewrite 调 timeout / 加 wait
DATA_ERROR setup 失败 + 数据问题 ✅ 调 api-testdata-cleaner
SCRIPT_ERROR AttributeError / Deprecated API ✅ AST rewrite(typo / 废弃 API / 异步等待)
BUG Page Error / 网络 5xx ⚠️ 注入 xfail/flaky marker

环境错误 (浏览器没装、依赖缺失、端口占用、服务没起)、定位错误 (元素找不到了)、超时错误 (元素在但渲染慢)、数据错误 (脏数据、唯一约束冲突)、脚本错误 (方法名写错、用了废弃 API)、真实缺陷(控制台有页面报错、接口 5xx)。

判定还有优先级。环境排第一,因为环境挂了,后面所有失败都无意义。真实缺陷排第二,因为它是根因,其余按可修复性依次排下去。

以前靠人猜的事,现在对着信号表一条条判。误判率降下来,「环境问题提单给开发」这种乌龙就没了。

2. 不仅给出建议,还能帮你直接修

分完类,每一类直接对应修复动作,不是给你一段「建议排查」的文字。

超时问题,直接改页面对象层,等待时间调大,或者补上等待页面加载完成的语句。

定位漂移 ,拿 pages.yaml 里的标准定义做对比,再从失败快照里找候选元素,推断出新的定位器。

iframe 问题,自动补上框架切换。

环境缺失,直接执行安装,浏览器没装就装浏览器。

脏数据,调起数据清理技能处理。

真实缺陷,在配置里打上标记,让这条用例以「预期失败」的状态存在,报告里明确标出「疑似产品缺陷,建议提单」。

3. 修完自动验证,不行就回滚

每一处代码修复,自动重跑那一条用例验证。

修好了,保留。没修好,自动回滚到备份文件,报告里如实写「修复未生效,建议人工介入」。

不会出现「AI 改完拍拍屁股走人,跑没跑得通不知道」的情况。修复的效果,它自己先验一遍。

4. 全程留痕,报告说话

所有执行过的命令写进审计日志,所有改过的文件留有备份,最后产出一份修复报告。报告里有分类统计(这轮失败里环境问题占几条、真 bug 占几条)、根因统计(哪类根因最频繁)、每条失败的明细(分类、根因、做了什么修复、改了哪个文件)。

以前「踩过的坑记不住」的问题,这里顺手解决了。跑上几轮,哪个模块最脆弱、哪类问题最频繁,报告直接告诉你。

四、Skill 实战演练

人工模拟失败

在脚本自动化执行的验收环节中,失败截图、异常录屏、用例故障根因诊断、报错脚本自动修复等能力,都需要依托真实的脚本报错场景才能完整验证功能有效性。

如果调试阶段,脚本执行全部通过,我们无法确认故障处理逻辑、兜底机制、修复流程是否能正常触发,极易出现 "功能开发完成,但真实报错场景下完全失效" 的隐性缺陷。

因此在验收自动化配套能力前,建议主动、可控地模拟各类脚本失败案例,人为制造稳定可复现的报错环境,完整校验整套故障处理链路的可用性、完整性与准确性。

以 UI 自动化脚本为例,最简便、稳定、无业务副作用的模拟方式:人工修改页面元素定位表达式,主动破坏 XPath、CSS 选择器、元素 ID、className 等定位属性,使脚本运行时稳定抛出「元素未找到」异常,实现 100% 复现的失败场景。

比如,下述我们以用户登录正常场景为例:

人工手动修改登录页面对象中属性值,比如修改用户输入框的属性值,故意在placeholder中增加一个空格:

重新跑测试

Claude Code中,重跑一轮,P0级冒烟测试用例:

复制代码
跑一下 shop-lab-ui-test 的 P0 冒烟用例

从执行结果可知,8条用例,仅有2条(用户注册的脚本执行成功),与用户登录或者依赖用户登录的相关脚本全部执行失败了。

而失败/错误的原因都是指定:

复制代码
Locator.wait_for: Timeout 10000ms exceeded --- waiting for get_by_placeholder("请输入 用户名") to be visible

失败的原因,是由于 login 页面用户名输入框 10 秒内没出现,login 用例直接 FAILED,search 用例因 fixture 调 login 在 setup 阶段 ERROR。

当然,别着急,这些用例执行报错是在我们的预期之内,和我们上述人工模拟的错误完全吻合,已经达到模拟用例失败的目的了。

验证用例失败后的产出物

查看test-results目录下的 summary.md(UI测试执行概览报告)

查看test-results目录下的 failure_analysis.md(失败用例故障分析报告)

进入到test-results-> pytest-raw目录,查看是否有生成失败截图(png格式)、录屏(webm格式)、trace.zip等文件。

自动修复元素定位失效问题

我们调用ui-failure-diagnoser技能,让其自动修复shop-lab-ui-test项目脚本最近一次执行失败的用例。

在技能列表中选择 ui-failure-diagnoser,输入一句指令。

bash 复制代码
/ui-failure-diagnoser 刚才那轮跑挂的用例,帮我诊断一下,
能修的自动修,修完验证一下

从上述执行结果可知,在利用ui-failure-diagnoser技能自动诊断失败用例时,建议最好提供pages.yaml文件路径,让其作为基线数据对比。

失败用例修复执行完成后,还会在test-results目录下,生成一份ui_repair_report.md(UI失败修复诊断报告),在报告里还会注明具体修改的代码位置,改动的具体代码等信息。(此次已经成功的将之前我们人工模拟的元素定位变更导致的登录脚本报错的问题,自动修复好了)

上述是以元素定位变更作为案例完成演示,但真实项目迭代场景远比示例复杂:前端版本迭代时经常会出现页面大规模重构、整体 DOM 层级调整、批量组件类名修改、Element Plus 弹窗 / 下拉组件 Teleport 挂载逻辑改动等情况,会造成数十甚至上百个页面元素的定位信息同步失效。

如果沿用传统人工维护模式,测试人员只能逐行遍历报错日志、逐个打开前端页面核对 DOM、手动修改pages.yaml配置与 Page 页面对象脚本,整套修复流程若是人工操作下来,存在三大显著痛点:

  • 1、修复周期极长,大面积变更场景下需要投入大量人力反复核对;
  • 2、人工操作极易出现遗漏,部分低频执行、次要模块的失效元素容易被忽略,遗留隐性自动化缺陷;
  • 3、重复机械操作占用大量测试工时,挤占业务用例开发、流程验证的核心工作时间,自动化脚本维护成本居高不下。

但现在,依托 AI Agent Skill 能力,我们可以彻底解决大面积页面改版带来的脚本批量修复难题,形成标准化自动化修复闭环,完整操作链路如下:

  1. 前端页面迭代发布、DOM 结构完成改动后,无需人工逐条梳理变更元素,直接调用ui-page-parser页面解析技能;
  2. ui-page-parser会自动遍历目标页面,抓取最新 DOM 节点、组件属性、可用 CSS/XPath 定位表达式,批量生成与当前页面完全匹配的全新pages.yaml标准页面对象基准文件,一次性同步所有元素的最新定位信息;
  3. 将全新生成的pages.yaml基准文件作为入参,传入ui-failure-diagnoser故障诊断修复技能;
  4. ui-failure-diagnoser会自动对比旧版脚本、定位配置、当前运行页面 DOM 快照与新版pages.yaml等数据,智能识别所有因页面元素变更引发的定位失败用例,批量完成修复动作:
  5. 批量修复完成后,可直接通过ui-test-executor执行调度技能重跑全量用例,验证所有页面改版相关缺陷全部修复生效。

整套流程全程无需人工逐点排查、手动修改代码,从页面解析、基准文件更新到批量自动修复全部由 AI 技能串联完成,大幅降低大规模 UI 改版后的自动化维护成本,同时规避人工漏改、改错带来的脚本不稳定问题,真正实现页面迭代与自动化脚本维护的无缝同步。

自动修复页面加载Flaky问题

经过上一轮 AI 批量自动修复后,所有由页面元素定位变更引发的脚本报错已全部处理完毕,绝大多数业务用例均可正常稳定执行。

但其中商品搜索模块的 3 条参数化用例(分别使用手机、小米、手表作为搜索关键词)依旧持续执行失败,这类报错和元素定位失效不属于同一类故障根源,属于典型的 UI 异步加载时序类 Flaky 问题。

为什么搜索有时会出现报错?原因其实很简单:

在脚本执行搜索业务流程时,整体操作时序如下:

输入搜索关键词→点击搜索按钮发起后端查询接口→前端异步请求商品列表数据并渲染页面

而脚本内置的基础断言逻辑往往并没有增加针对性的加载状态等待判断,仅在点击搜索后立刻执行结果校验。

当网络存在波动、接口响应存在加载延迟时,后端商品数据尚未返回、页面商品列表 DOM 还未完成渲染,页面会短暂展示 "暂无商品" 空状态;

此时脚本会提前触发断言,对比页面实时内容与预期的商品列表数据,直接判定用例失败。简单来说:页面数据还没加载完成,断言就提前执行,时序错位造成校验不通过

针对这类页面异步加载Flaky问题,可以仍然可以直接调用ui-failure-diagnoser 技能 自动帮我们修复。

该类异步时序加载问题在UI 自动化测试中非常常见,也是UI自动化高频不稳定用例的核心来源之一

即便页面元素配置完全正确,网络、接口、前端渲染速度的微小波动都会导致用例偶发失败。而依靠Agent Skill 体系的智能等待策略、故障分类诊断能力,无需人工逐行修改每条搜索用例代码,由Skill统一封装全局异步等待逻辑,从底层消除加载延迟导致的校验报错,大幅降低脚本不稳定性。

五、小结

先说说我的真实感受。

这套东西实测用下来,最打动我的地方不是修得多快,而是「失败」这件事的性质变了。以前失败是负担,一片红条意味着一下午的排查;现在失败是数据,每一条都有分类、有根因、有处理结果。跑上几轮,哪个模块最脆弱、哪类问题最频繁,报告直接摆在你面前。测试团队第一次可以拿着失败统计去聊质量,而不是抱着一堆待办去救火。

也有人问我,让 AI 去改测试脚本,不怕失控吗。

我恰恰觉得,人肉维护才是最容易失控的那种。改漏了、改错了、拖着不改了,这些每天都在真实发生,而且没有任何记录。AI 修复反而处处留痕,改什么有备份,改完自动重跑验证,跑不通自己回滚,每一步操作都躺在审计日志里。真要追溯起来,它比自己上周改了什么记得清楚得多。

当然,边界必须讲清楚。ui-failure-diagnoser 接管的是「分类、定位、修复、验证」这些有规则可依的活,它有一条硬约束,永远不碰测试用例的断言和业务语义。下面这些事,仍然需要人来把关。

AI 负责的事 人负责的事
六类失败自动分类 抽查分类是否准确,尤其真缺陷那一条
定位漂移自动修复 Review 修改的定位器是否符合业务语义
环境缺失自动安装 确认 CI 环境的变更是否符合团队规范
脏数据自动清理 判断数据问题背后的流程漏洞
真实缺陷打标并高亮 确认缺陷、写清复现步骤、提交开发

特别提醒一句。「预期失败 」的标记是双刃剑。AI 基于控制台报错判定真缺陷,准确率很高,但标记本身不能代替确认。把所有失败都打上标记让报告变绿,是用另一种方式掩盖问题。标记是给排查让路的,不是给漏测开门的。

回顾一下整个过程。

痛点。 失败原因靠人猜,误判代价高,证据不会关联,批量失败没人查,踩坑没记录,修复靠人肉。

方案。 ui-failure-diagnoser 把诊断固化成「失败加载、分类判定、根因定位、自动修复、验证报告」的五步流程。按信号分类不靠感觉,看证据判方向,修复直接落地并自动验证,全程留痕。

效果。 实战里的几轮验证最有说服力。人工模拟的定位失效,一句指令自动修复,连改动位置都写进报告;前端大改版导致几十个元素批量失效的场景,接上页面解析技能重新生成基准文件,整条链路照样自动跑通;连最顽固的异步加载 flaky,也从根上治了。这些活以前是一天起步,现在是几分钟加一份报告。

边界。 AI 负责诊断和修复,人负责定性和提交。断言和业务语义,永远是人的领地。

大家可以自己根据本文提供的思路开发 skill,如果需要现成的教程和 skill,也可以加入「狂师 . AI 进化社」获取,里面有各类 AI 技术落地保姆级图文教程、视频教程,包括 AI 测试全流程的实战教程(保姆级手把手喂饭教程,跟着教程操作,零基础也能快速上手。

温馨提醒,「AI 测试」只是 AI 进化社八大技能版块之一。

最后多说一句。我一直觉得,UI 自动化做不下去的团队,很少是脚本写不出来,大多是维护不动了。脚本维护吞掉的时间,才是测试同学身上最被低估的成本。把这部分交出去,人的时间才能回到真正值钱的地方,看风险、判质量、守住发布前的那道门。

到这里,执行和诊断两环都理顺了。跑完有证据,失败有结论,修复有验证。

下一篇,我们把这些攒下来的执行结果、诊断结论和历史数据,交给 ui-report-generator,变成一份能支撑发布决策的测试报告。我们下篇见。