当AI学会像用户一样“乱点”,那些藏在代码深处的定时炸弹就藏不住了
大家好,我是某互联网公司质量保障团队的技术负责人,负责移动端稳定性测试体系建设。
今天聊一个我们最近做成的实验——用AI模拟10万个不同性格的真实用户,在App里“疯狂探索”,然后找到了产品经理做梦都想不到的崩溃路径。
先上结果:系统上线四个月,累计发现了127条人工测试和传统自动化完全漏掉的崩溃路径,其中23条是P0级——一旦触发就是App闪退、用户流失的那种。
关键是,这些路径没有一条在产品PRD里出现过。
一、为什么传统测试找不到“真崩溃”?
说个真实的数据:主流App需适配超过20,000种设备-OS组合,用户行为路径复杂性导致30%以上崩溃未被预发现。
30%。也就是说,每三个崩溃里就有一个是上线后才被用户“撞”出来的。
原因其实很简单——测试用例是“好人”写的。
测试用例:打开App → 登录 → 浏览首页 → 点击商品 → 加入购物车 → 支付
真实用户:打开App → 疯狂滑动 → 点进一个页面 → 立刻返回 → 再点进另一个 → 快速切换Tab → 在加载中点了三次 → App卡死了
正常用户不会按照用例操作,暴躁用户更不会。
我们的产品经理在PRD里写的都是“理想路径”——用户会乖乖登录、按流程操作、耐心等待加载。但真实世界里的用户:
网络不好时疯狂重试点
加载转圈时连续按返回
在页面还没渲染完时就滑动
在不同Tab之间来回快速切换
这些操作没有一个写在需求文档里,但每一个都可能触发崩溃。
二、转折:让AI学会当“坏用户”
去年年底,我们开始了一个项目——训练AI模拟不同性格的真实用户,对App做大规模探索式测试。
核心思路来自一个很朴素的想法:大语言模型经过海量通用知识训练,具备一定的模拟人类常识与预期的能力,恰好契合模拟用户行为的需求,且无需针对特定应用单独适配,天然具备泛化性。
翻译成大白话:AI知道“正常人会怎么用App”,也知道“暴躁的人会怎么搞破坏”。
我们给AI设定了三类“用户画像”:
第一类:正常用户(占比60%)
按常规路径操作,偶尔滑动、偶尔返回
用于建立“基准行为基线”
第二类:急躁用户(占比25%)
操作节奏快、不等加载完成就进行下一步
频繁切换页面、快速滑动列表
在加载动画出现时连续点击
第三类:探索型用户(占比15%)
专门点那些“看起来不像按钮”的地方
长按、双击、三指滑动
在页面边界和角落疯狂试探
三类用户加起来,我们让AI模拟了10万个独立的“虚拟用户” ,每个用户在App里执行5-15分钟的“自由探索”,然后记录所有操作序列和App的响应。
三、技术方案:怎么让AI“学会”乱点?
技术实现上,我们走了三条路。
路径一:大模型驱动UI理解
传统自动化测试依赖XPath和ID定位——UI一变就挂。我们的方案是多模态模型直接“看”屏幕。
每次AI“看到”一个页面,多模态模型会:
识别所有可交互元素(按钮、输入框、滑动条、Tab)
理解每个元素的语义(“这个是返回”“这个是提交”)
根据当前用户画像,决定“点哪个”和“怎么点”
这套方案参考了美团的KuiTest思路——让大模型理解UI交互组件的功能,预测点击后的合理结果。不同的是,我们刻意让AI“预测不合理的结果”——专门找那些“点了之后会出问题”的操作。
路径二:Delta-Debugging路径压缩
AI探索过程中会产生大量操作序列,有些长达几十步。但真正导致崩溃的,往往只是其中某几步的组合。
我们引入了一个基于Delta-Debugging二分算法的路径压缩模块:
当AI触发了一个崩溃,系统记录下完整的操作序列(比如15步)
然后自动尝试删除序列中的某些步骤,看崩溃是否还会复现
反复二分,直到找到能复现崩溃的最短路径
举个例子:AI用12步操作触发了一个崩溃,路径压缩后可能发现——只需要“快速切换Tab3次”就能复现。
这个功能的价值怎么强调都不为过。测试团队拿到的不再是“崩溃日志+长串操作录像”,而是精准的、可复现的最小崩溃路径——开发同学一看就知道问题在哪,修起来快太多了。
路径三:多智能体协同探索
单靠一个AI到处乱点,效率太低。我们部署了一组AI智能体并行探索:
每个智能体独立运行,有不同的“探索策略”
有的专注“深层路径”(点进深层页面再操作)
有的专注“边界路径”(在页面边缘和角落操作)
有的专注“快速切换”(在页面间高频跳转)
10万个虚拟用户,实际上是10万个并发的AI探索任务,分布在我们的云真机集群上并行执行。
四、真实案例:那些“产品经理不敢写”的崩溃
说三个AI找到的真实案例。
案例一:“快速返回”触发的内存泄漏
AI在模拟“急躁用户”时发现:在商品详情页快速点击返回按钮5次以上,App会逐渐变卡,第7-8次时直接闪退。
开发排查后发现:每次返回时,详情页的图片缓存没有被正确释放。正常用户返回一次,内存还能撑住。但急躁用户连续快速返回,内存泄漏累积到阈值,直接OOM。
产品经理看到这个Bug时的表情:“谁会连续点那么多次返回啊?”
我反问:“你见过用户骂一个加载慢的页面时怎么操作的吗?”
案例二:“加载中连续点击”导致的ANR
AI在模拟“网络差环境下的暴躁用户”时发现:在弱网环境下,在加载转圈出现时连续点击屏幕任意位置3次,主线程会被彻底卡死,触发ANR(应用无响应)。
原因是:每次点击都会触发一个等待队列的检查,而加载中的页面状态没有做防抖处理。正常用户等加载完成再操作,永远不会触发。但暴躁用户会在加载时疯狂点屏幕——“怎么还没好?点一下!再点一下!”
这个Bug我们修复后,线上ANR率下降了12%。
案例三:“跨页面快速切换”导致的状态错乱
AI在模拟“探索型用户”时,发现了一个极其隐蔽的问题:从首页→分类→详情→返回首页→再点分类→再进详情→快速返回——在特定节奏下,页面栈会被污染,导致“返回”按钮跳转到错误的页面。
这个Bug产品经理完全无法理解:“用户怎么会这么操作?”但线上数据告诉我们,每天有数千个真实用户就是这么操作的——他们只是“手快”而已。
五、踩过的坑(说三个最痛的)
坑一:AI“太聪明”了,反而不像真人
初期,AI的操作非常“高效”——每次都能精准找到按钮、快速完成任务。但这根本不像真实用户。
解法:我们给AI加入了“不确定性因子”——随机延迟(100-800ms)、随机滑动偏移、偶尔的“误触”(点偏5-10像素)。让AI的操作更像“手残”的真实用户。
坑二:探索空间太大,跑不完
一个中等复杂度的App,页面状态组合是天文数字。AI如果无限制探索,跑三天三夜都跑不完。
解法:引入覆盖率引导——优先探索“没去过”的页面和“没试过”的操作组合。同时设置探索上限(每个虚拟用户最多15分钟),超时自动停止。
坑三:误报太多
初期,AI“发现”的崩溃里,60%以上其实是测试环境的问题——网络抖动、设备过热、测试账号权限不足。
解法:建立了三级验证机制:
AI发现疑似崩溃 → 自动在同一设备上重试3次
3次中至少2次复现 → 标记为“高置信度”
高置信度问题 → 进入人工复核队列
这套机制把误报率从60%降到了8% 。
六、效果数据
说几个硬数据:
指标
数据
模拟虚拟用户数
10万+
累计发现崩溃路径
127条
P0级崩溃
23条
人工测试漏测率
从30%+降至<5%
路径压缩效率
平均12步→3步
线上ANR率(案例二修复后)
↓12%
最关键的变化:测试团队从“按PRD写用例”变成了“让AI找PRD之外的崩溃” 。我们不再只验证“产品想让用户怎么用”,而是验证“用户实际会怎么用”。
七、给同行的一些建议
如果你也想尝试这个方向,我有几点实在的建议:
- 从“用户画像”开始,别一上来就搞全量探索
先定义清楚你要模拟哪几类用户——正常、急躁、探索型就够了。每种画像的操作模式差别很大,混在一起AI会“精神分裂”。
- 路径压缩比探索本身更重要
找到崩溃只是第一步。能不能给出最短复现路径,决定了开发愿不愿意修。 一个15步的崩溃录像,开发看都不想看。一个3步的精准复现步骤,开发当天就修了。
- 别在真机上跑,用云真机集群
10万个虚拟用户如果都在本地真机上跑,你得买多少台手机?我们用的是云真机集群,并行跑、按需扩容,成本可控。
- 接受“AI找到的不全是Bug”
AI会找到很多“看起来像Bug但其实不是”的东西——比如设计如此、或者测试环境问题。建立分级验证机制,把人工复核的工作量降到最低。
- 先跑非核心模块
别一上来就让AI去折腾支付流程。先从非核心、低风险的模块开始跑(比如设置页、个人中心、帮助中心),跑通了再逐步扩展到核心业务。
最后
AI模拟用户操作做探索式测试,本质上是在做一件事——把“真实用户怎么用App”这个黑盒打开。
产品经理写PRD的时候,假设用户是“理性的、耐心的、按流程走的”。但真实世界里的用户是“急躁的、手快的、乱点的”。这两者之间的差距,就是崩溃藏身的地方。
AI不会替代测试工程师,但它帮我们找到了那些“产品经理都不敢写进PRD”的崩溃路径。
而这些路径,恰恰是用户每天都在撞的。