雪球 RN 应用前端自动化测试实践:基于 Airtest 的全链路解决方案

一、RN(React Native)业务背景与挑战

RN技术定位

雪球核心业务(如基金交易、社区互动)采用RN开发,实现iOS/Android代码共用,提升迭代效率。但RN的动态界面特性(如组件动态渲染、异步加载)给自动化测试带来以下挑战:

  • 界面元素不稳定:无固定ID的动态按钮、列表项导致传统控件定位失效;
  • 跨端兼容性:iOS与Android的UI渲染差异显著,混合开发模块(RN+原生)适配困难;
  • 实时数据依赖:基金净值、交易限额等实时接口延迟影响脚本执行稳定性。

二、自动化测试工具链选型

Airtest

跨平台图像识别,模拟用户点击、滑动等操作

定位无固定ID的动态按钮、弹框

Poco

UI控件精准识别与断言(支持RN组件树解析)

校验文本内容(如支付提示、错误信息)

pytesseract

OCR文字识别(结合图像处理)

解析动态渲染的文本(如基金净值截图)

Mockoon

接口模拟服务(支持动态模板与代理转发)

隔离后端依赖,稳定测试环境

三、OCR技术在RN自动化中的深度应用

1. 技术实现链路

  • 核心步骤: 区域截图:使用Airtest的capture_screen()获取目标区域(如定投周期选择器);预处理优化: 灰度化(Image.convert("L"))减少色彩干扰;二值化(阈值调整)分离文字与背景;文字解析:通过pytesseract.image_to_string()识别中英文混合文本;业务断言:验证识别结果是否符合预期(如“每周周五”定投周期)。
2. 实战示例:定投周期动态文本校验
  • 场景:RN自定义定投周期选择组件(无原生控件,文本通过Canvas渲染)。
  • 实现代码
img = G.DEVICE.snapshot(rect=(500, 800, 700, 900))  # 截取选择器区域  
processed_img = img.convert("L").point(lambda x: 0 if x < 180 else 255)  
cycle_text = pytesseract.image_to_string(processed_img, config="--psm 7")  
assert "每周" in cycle_text, "定投周期识别失败"  
  • 优化点:通过config="--psm 7"指定单行文本模式,提升识别准确率。

四、RN链路业务自动化示例:基金买入全流程

1. 业务流程拆解

搜索基金

Airtest图像点击搜索框 + Poco断言结果列表

基金名称文本与代码匹配

选择子账户

Poco遍历列表组件 + 图像点击确认

子账户名称正确回显

金额校验

OCR识别最低买入金额 + Poco动态文本断言

组合支付逻辑(现金宝+银行卡额度)

密码输入

Airtest图像模拟安全键盘点击

避免原生控件Hook引发安全风险

结果验证

Airtest图像比对 + Poco界面跳转断言

资产列表页显示最新交易记录

2. 代码片段:组合支付逻辑校验
def combine_pay_tip_assert():  
    tip_text = poco(textMatches="先从现金宝扣款.*").get_text()  
    assert "现金宝" in tip_text and "银行卡" in tip_text, "组合支付提示缺失"  

五、RN自动化测试核心问题与解决方案

动态界面定位

列表项无固定ID、弹框随机生成

Airtest图像识别 + Poco层级遍历(如

offspring()

跨线程延迟

RN调用原生API后元素未加载完成

显式等待(

wait(Template("加载图标.png"))

动画干扰

滑动加载时元素位置动态变化

精准坐标滑动(

swipe((x1,y1),(x2,y2))

) + 动画周期

sleep()

混合开发兼容

RN与原生模块切换时控件识别失效

多框架混合使用(RN界面用Poco,原生界面切Appium)

接口依赖

实时数据接口延迟导致脚本失败

Mockoon模拟接口响应 + Charles代理转发

六、自建自动化测试平台架构

1. 平台能力全景
  • 技术栈: 前端:React+Ant Design(脚本管理、报告可视化);后端:Flask+MySQL(执行记录)+ Redis+RQ(任务队列);执行层:Shell脚本调用Airtest,支持10+设备并行(iOS/Android)。
  • 核心特性: 多设备调度:随机/指定设备执行,支持同时运行20+脚本;Mock服务集成:一键切换真实/模拟接口环境,提升脚本稳定性;智能报告:自动标注失败步骤截图,支持日志与图像联动分析。
2. 并行执行优化
  • 通过Supervisor+RQ为每台设备创建独立任务队列(如“iPhone12”队列),实现硬件资源高效利用;
  • 执行效率对比:单设备串行需4小时 → 5设备并行仅需30分钟。

七、落地成果与未来规划

  1. 量化收益: 核心业务自动化覆盖率:70%+(基金交易、定投等高频场景);脚本执行成功率:从60%提升至92%(引入Mock服务后);人力成本:回归测试人力投入减少50%,脚本维护效率提升30%。
  2. 未来方向: AI赋能:探索基于计算机视觉的自动脚本生成,降低界面变更维护成本;全链路覆盖:扩展至社区互动、投顾服务等复杂业务流程;边缘场景支持:适配折叠屏、平板等小众设备,提升兼容性测试效率。

总结

雪球团队通过“图像识别+控件定位+OCR文本解析”的立体化方案,结合自建自动化平台,系统性解决了RN应用的测试难题。该方案以基金交易流程为典型切入点,展现了从技术选型、场景落地到工程化实现的全链路实践,为同类RN项目提供了可复用的测试范式。未来,随着AI技术的深度融入,前端自动化测试将向“低代码、自维护”方向进一步演进,持续释放效率红利。

我的反思:Airtest图像识别 + Poco层级遍历是啥 怎么搞?

场景 1:动态生成的按钮(无固定 ID)

  • 问题:RN 应用中通过 JS 动态生成的按钮,无稳定 ID 或 XPath。
  • 解决方案:Airtest 图像识别:截图按钮作为模板,使用touch(Template("btn_buy.png"))点击。Poco 层级遍历:点击后通过poco("支付成功").exists()验证结果。

场景 2:复杂列表项操作

  • 问题:列表项包含动态内容(如基金名称、净值),需精准定位特定项。
  • 解决方案:Poco 层级遍历:通过poco("ListView").child("Cell")遍历列表项。Airtest 图像识别:对特定项中的图标(如 “加自选”)截图匹配并点击。
全部评论
说实话,我感觉我这篇文章还是对大伙儿找工作来说一些场景问题还是挺有帮助的,但大家都没人看,哈哈。
点赞 回复 分享
发布于 06-08 10:47 北京

相关推荐

头像
06-11 23:35
美团_测试开发
&nbsp;&nbsp;今天主要说说我之前实习那会是怎么过来的以及大家以后做实习生了有什么建议给大家。入职一年不到就要开始下楼去接我的实习生了,之前虽然也带过一些实习生啥的但是主要是别人教的,我主要就是带带他们测需求或者写一些工具啥的,没有归属感。我实习那会:煮包我是大三那会开始实习的,当时是在快手,我在牛客的第一篇帖子就是23年那会拿到快手的offer,作为双非二本的我还是很开心的。首先实习第一天就是配环境其它不用做什么有时间可以再熟悉一下业务啥的。公司招实习生的目的主要是做一些杂活技术含量一般要求不高,除非是校招实习拿到offer再去实习,这种一般会好好培养或者做一些技术含量大的工作。普通实习生一般要是想学东西就得靠自己去看看公司的课或者相关的文档啥的,学习进步的过程往往是痛苦的,煮包我当然是吃不了一点苦的那会,所以快手实习两个月基本啥也不会就混了个实习经历,再后来痛定思痛感觉再不学一些东西面试都没东西讲了,所以就详细了解了一下业务,主动申请写写自动化,然后当时还学了kafka,我的导师晚上化作面试官对我提问。真的很不错,再后来就是大四下因为学校要求所以过完年就去美团提前实习了,因为是我主动要去的,所以当时就没啥工作基本都在摸鱼,每天就是逛我们内部的话题看看相亲贴啥的,就这样两个月也没测过需求就学了学工具基本没有成长吧,也是为我下半年入职埋了雷吧,出来混迟早要还的。建议:如果你是大三或者研二这种的,我的建议是可以努努力争取转正啥的,或者多去学学公司的内部资料,特别是基础一般的一定要乘着这个机会去学,文档没有权限就大胆的申请,私信求大哥大姐们给审批一个权限。“哥,我是刚来的实习生可以辛苦给审批个权限吗,我要学一下这个东西”。这个是我常用的话术,一般人都不会拒绝的。如果是大四考研上岸的这种,俗称“大爷”,这种可以随时跑路,干的不喜欢跑就完事了。之前我就遇到个,项目干了一半了跑了,然后我加班好几天才给补救回来,一开始信誓旦旦的给我说我干完了才会走,结果发现不好搞就直接跑路了,我真的丢了呀。我相信我的新实习生不会这样的,我要励志成为一个好mt。最后:有个好的导师真的很重要,可以少走很多的弯路,也希望大家能拿到满意的offer遇到很好的导师&nbsp;&nbsp;
宏夏c:我实习时候的mentor已经跳槽了
点赞 评论 收藏
分享
11距离秋招落幕已逾半年,这六个月里我不断尝试新事物,也对个人成长路径与技术方向进行了系统复盘。此刻提笔续写秋招终章,既是为这段旅程画上句点,亦是对过往的郑重告别。我的编程生涯可用八字概括:兴趣驱动,野蛮生长。•&nbsp;2017年(初二)初识脚本编程,解锁游戏之外的数字世界•&nbsp;2018年(初三)钻研游戏破解技术,在技术社区习得伪黑客知识•&nbsp;2019年(高一)通过二次开发开源项目发布首个独立软件,命运的齿轮就此转动•&nbsp;2020年(高二)疫情期间潜心开发,见证互联网生态的蓬勃演进&nbsp;&nbsp;◦&nbsp;2020.02&nbsp;发布第三代软件版本,首次体验流量爆发与用户激增&nbsp;&nbsp;◦&nbsp;2020.04&nbsp;凭借广告收益创立工作室,同步试水自媒体运营•&nbsp;2021年(高三)暂别开发专注备考,正常考入985高校•&nbsp;2022年(大一)系统构建技术体系,掌握全栈开发技能,完成从爱好者到开发者的蜕变•&nbsp;2023年(大二)践行技术理想,主导多个产品开发并参与开源协作&nbsp;&nbsp;◦&nbsp;2023.06&nbsp;借AI浪潮开启创业尝试,采用双公司合作模式运营•&nbsp;2024年(大三)因创业回报不及预期及课业压力,回归独立开发轨道•&nbsp;2024.06(大四)整合技术体系,备战秋招•&nbsp;2024.11&nbsp;收获多家头部企业SSP&nbsp;offer•&nbsp;2025至今&nbsp;暂别代码,感受生活两大关键转折:1.&nbsp;高中时期的超额正反馈,为职业选择注入持续动力2.&nbsp;及时终止创业项目,确保秋招窗口期的精力投入成长Q&amp;amp;AQ1&nbsp;为何专注前端领域?作为独立开发者,前端是我技术栈中最具优势的环节。我的学习哲学是&amp;quot;实践中成长&amp;quot;,而优秀的前端交互能为产品带来直接价值。相较于需要应对高并发等复杂场景的后端,前端更契合我的兴趣与能力长板。Q2&nbsp;如何看待学历价值?职业选择的核心标准应是兴趣导向。若学历能助力获得心仪工作,便是物尽其用。即便当年考入更好级别的学校,我依然会选择这条技术路径——热爱与学历无关。Q3&nbsp;内容发布规划?•&nbsp;求职干货:牛客网•&nbsp;成长思考:小红书Q4&nbsp;无大厂实习的竞争力?虽无传统实习经历,但简历呈现:1.&nbsp;自认为校招阶段较出色的全栈能力2.&nbsp;持续运营的主力项目3.&nbsp;多款上线产品的作品集4.&nbsp;活跃两年半的GitHub贡献记录5.&nbsp;百星开源项目主导者身份6.&nbsp;各平台产品认证资质7.&nbsp;技术博主及小团队领导经验8.&nbsp;互联网各角落的各种足迹(近三年)谨以此文,致敬那个野蛮生长误打误撞的二十二载青春。未来将继续在小红书分享成长感悟,牛客网专注求职干货
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务