AICon日程100%就绪,9折倒计时最后一周 了解详情
写点什么

Flutter UI 自动化测试技术方案选型与探索

  • 2021-06-11
  • 本文字数:2693 字

    阅读完需:约 9 分钟

Flutter UI自动化测试技术方案选型与探索

Flutter 页面无法直接使用 Native 测试工具定位元素,给自动化测试带来很多不便。虽然 Google 官方推出了 Flutter driver 和 Integration test,但是在实际使用中存在以下问题:

  • 不适用于混合栈 APP,虽然 appium 中有相关的 driver,但是无法切换环境。

  • 元素定位能力相对薄弱。

  • 依赖于 VMService,需要构建 Profile 或 Debug 包。


基于以上因素,我们并没有直接使用 Google 官方推出的工具,而是选择基于 Native 测试工具去扩展 Flutter 页面的测试能力。本文对 Flutter driver 和 Integration test 的原理和实现进行了分析,同时简单介绍闲鱼在 UI 自动化测试的尝试方案。

Flutter driver

最早接触 flutter 自动化测试时,先尝试使用 appium 框架去驱动 APP,当我们使用 inspect 功能去 dump 页面元素时发现很多元素会被合并成一个区域块,然后点击的时候只能通过 xpath 定位,想定位到某些具体的元素会比较困难,并且 xpath 其实是容易改变的,代码可维护性能力差。


因为上述原因,我们开始调研 Flutter 官方提供的测试工具——flutter driver。一开始使用该框架的时候发现它只能适用于纯 Flutter 应用,对于混合栈应用并不适应,但是它底层提供的元素定位能力或许对我们有用,于是我们对它的源码进行了剖析,该框架的原理图 1 如下所示。

null

图 1 flutter driver 原理图 


整个框架的流程交互比较简单,测试脚本在运行时,首先利用 FlutterDriver.connect()来连接 VMService 获取相关的 isolate,之后通过 websocket 来传输操作过程以及数据获取。其中测试脚本侧的所有操作都是被序列化为 json 字符串通过 websocket 传递给 ioslate 来转换为命令在 APP 侧执行,例如我们想要获取某个组件的文本内容,其最终生成的 json 结构体如下:


{    "jsonrpc":"2.0",    "id":5,    "method":"ext.flutter.driver",    "params":{        "finderType":"ByValueKey",        "keyValueString":"counter",        "keyValueType":"String",        "command":"get_text",        "isolateId":"isolates/4374098363448227"    }}
复制代码


了解上述原理后,就可以通过构造协议格式,在任何语言、测试框架下都能够去驱动 flutter 测试,所以我们对这个协议进行了封装,使用 Python 进行驱动,这样可以在使用 uiautomator2 和 facebook-wda 的基础上来测试 flutter 页面,以满足 flutter 混合栈应用的测试需求。最终的实现代码 demo 如下。


from flutter_driver.finder import FlutterFinderfrom flutter_driver.flutter_driver import FlutterDriverimport uiautomator2 as u2
if __name__ == "__main__": d = u2.connect() driver = FlutterDriver(d) if pageFlutter is True: # 如果是flutter,则使用flutter driver进行驱动 driver.connect("com.it592.flutter_app") finder = FlutterFinder.by_value_key("input") driver.tap(finder) time.sleep(1) print(driver.getText(FlutterFinder.by_value_key("counter"))) else: d(text="increase").click()
复制代码


我们尝试使用该套框架,发现其实 flutter driver 底层提供的能力相对比较薄弱,并不能完全满足我们的需求,主要问题如下:

  • 不能批量操作元素,一旦 finder 定位到的元素超过 1 个时,就会抛出异常。

  • 很多时候开发同学不写 key,元素定位也没那么方便。

  • 因为 flutter 没有 inspect 工具 dump 元素,所以只能利用结合源码去写脚本,代码维护成本比较高。

  • 官方已经放弃维护该项目,所以后续估计也不会有新功能支持。

integration_test

前面提到,flutter 官方放弃维护 Flutter driver,并推出新的测试框架 integration_test,那么这个框架会不会对混合栈应用予以支持呢,事实上试用了之后发现事情并没有我们想的那么美妙。在官方文档里有这么一句话“该软件包可在设备和模拟器上对 Flutter 代码进行自驱动测试”。


integration_test 底层的元素操作和定位还是基于 flutter_test 去驱动的,其优势主要如下:

  • 测试脚本可以使用各种 Flutter 的 API。

  • 打包 ipa、apk 后就能在 Firebase Test Lab 等设备群上运行测试,不需要额外驱动。

  • integration_test 的每个页面之间测试无关联,可以实现单个页面级别的测试。


但是由于底层元素定位和 Flutter driver 的是一致的,所以 Flutter driver 存在的问题依旧存在,同时还存在其他局限问题:

  • 测试脚本打包到 APP 中,每次修改脚本都需要重新打包。

  • 对端到端测试不够友好,需要额外函数来等待数据加载完毕。

  • 不适合全链路级别的页面测试。

  • 可扩展性弱


基于以上问题,不满足我们的使用需求,所以我们只是做了简单预研,并没有深入了解和应用。

闲鱼 UI 自动化测试方案

学习 Flutter 官方推出的相关测试框架之后,我们开始思考闲鱼 UI 自动化到底要怎么走?是站在官方的肩膀上去造轮子还是复用现有的原生自动化测试能力去扩展 Flutter 测试能力。在综合考虑投入成本以及测试脚本的维护难度后,我们选择使用图像处理技术来扩充原生自动化框架对 Flutter 页面的测试能力支持,整个测试方案架构如图 2 所示。

null

图 2 闲鱼 UI 自动化测试方案架构

 

Flutter 的元素不是完全不能被 uiautomator2 和 facebook-wda 识别,所以编写测试脚本时只需要处理不能被识别的元素即可。对于有 name、label 以及 xpath 不易改变的元素定位,我们优先使用原生定位能力进行定位操作,其他元素则直接使用图像处理技术进行定位操作。


在处理无法使用原生能力定位的元素时,我们优先使用 ocr 文字匹配来进行定位,准确率较高,不容易受分辨率的影响,对于纯图片则通过图片查找的方式进行定位。对于一些常见的元素控件例如商品卡片、价格、icon、头像等,我们构建一个训练集,使用图像分类来判断元素的类型,从而实现常用控件的定位。

UI 自动化面临最大的问题就是——随着版本的迭代,测试脚本也需要进行不断迭代。所以在方案选型和脚本编写过程中需要考虑到脚本的健壮性以及可维护性。我们在实际脚本开发中将页面元素封装到单独的类中,并与测试逻辑分离,从而保证后期元素迭代时只需要修改对应的页面元素即可,减少维护成本。


null

图 3 脚本分层结构 


闲鱼性能自动化测试的相关 UI 操作已经使用该方案,在脚本编写时,并不需要区分当前页面是什么类型。我们的脚本已经稳定运行 500+次,成功率超过 98%。

总结

null

图 4 方案对比 


从图 4 可以看出,无论是 flutter driver 还是 integration test 对混合栈的支持不够成熟,但是 flutter driver 可以进行一些扩展,对于纯 Flutter 应用而言,采用该方案能够基本满足测试需求,而 integration test 相对没有那么成熟,对于混合栈应用的测试,可能还是需要考虑混合栈的场景切换成本,使用一些 ocr 技术去做一些扩充可能成本更低,收益更大。


本文转载自:闲鱼技术(ID:XYtech_Alibaba)

原文链接:Flutter UI自动化测试技术方案选型与探索

2021-06-11 13:003787

评论

发布
暂无评论
发现更多内容

LED透明屏市场前景展望

Dylan

全球经济下行 中美贸易 LED LED显示屏 led显示屏厂家

软件测试/人工智能丨成员运算符

测试人

人工智能 软件测试

在自动化测试时,Python常用的几个加密算法,你有用到吗

华为云开发者联盟

Python 开发 自动化测试 华为云 华为云开发者联盟

别划走!3分钟看懂 Git 底层工作原理

伤感汤姆布利柏

和鲸科技荣获第三届光合组织解决方案大赛集智赛道优秀奖

ModelWhale

人工智能 信创 数据科学 海光 光合组织

奥特曼被指爱权力胜过金钱;人类才是「幻觉问题」根本原因丨 RTE 开发者日报 Vol.103

声网

和鲸科技携手深圳数据交易所,“数据+数据开发者生态”赋能人工智能产业发展

ModelWhale

人工智能 数据要素 数据科学家 工业数字化 深圳数据交易所

Amazon CodeWhisperer 免费的 AI 代码生成助手!最新体验反馈~

亚马逊云科技 (Amazon Web Services)

人工智能 亚马逊云科技 云上探索实验室 Amazon CodeWhisperer

【FAQ】推送前台应用的通知处理功能没生效,如何进行排查?

HarmonyOS SDK

HMS Core

Android开发中如何进行单元测试?

高端章鱼哥

android 单元测试 JUnit Mockito

MySQL:从MySQL看主从架构高可用性实现

互联网工科生

MySQL 数据库

龙智DevSecOps研讨会年终专场来了!龙智、Jama与清晖敏捷专家邀您共探如何打好DevOps基础、赋能创新

龙智—DevSecOps解决方案

MongoDB和阿里云携手驱动WeLab 引领超千万用户迈向智能金融未来

Geek_2d6073

推出 Amazon EC2 C7i 实例

亚马逊云科技 (Amazon Web Services)

机器学习 分布式 ebs

GeminiDB Cassandra接口新特性PITR发布:支持任意时间点恢复

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 华为云GeminiDB

CSS属性isolation,走过路过不要错过!

伤感汤姆布利柏

CSS 前端

SVN优缺点详解及版本控制系统选型建议

龙智—DevSecOps解决方案

svn 版本控制

Blackhat Europe 2023 | 百度安全揭秘多平台NPU背后的安全风险

百度安全

寿光教育城乡一体化的秘诀,藏在“教育一朵云”里

脑极体

云平台

软件测试/人工智能丨身份运算符

测试人

人工智能 软件测试

Flutter开发微信小程序:如何构建一个简单的天气预报小程序

Geek_2305a8

四川大学携手和鲸打造课内workshop,趣味实践教学助力数据思维培养

ModelWhale

Python 数据分析 人才培养 数据思维 四川大学

2023滨海湾人工智能论坛举办,范向伟代表和鲸科技共同发起成立工业智能算法联盟

ModelWhale

人工智能 算法 大模型 算料 滨海湾

INTO领航:2023社交变革峰会揭示数字社交的未来格局

Geek_2d6073

Flutter UI自动化测试技术方案选型与探索_架构_闲鱼技术_InfoQ精选文章