AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

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:003967

评论

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

【刷题记录】2. 两数相加

WangNing

7月月更

Linux 下的传统 IPC 通信原理

北洋

Andriod 7月月更

1500万员工轻松管理,云原生数据库GaussDB让HR办公更高效

华为云开发者联盟

数据库 后端

从解析HTML开始,破解页面渲染时间长难题

华为云开发者联盟

html 前端 web开发 网页

阿里云易立:云原生如何破解企业降本提效难题?

阿里巴巴中间件

阿里云 架构 云原生

HAVE FUN | “飞船计划”活动最新进展

SOFAStack

微服务架构 开源软件 新手引导

从0开始创建小程序

小恺

7月月更

当 Knative 遇见 WebAssembly

阿里巴巴中间件

阿里云 容器 云原生 Knative WebAssenbly

华为小米互“抄作业”

科技新知

leetcode 53. Maximum Subarray 最大子数组和(中等)

okokabcd

LeetCode 动态规划 数据结构与算法

抖音或将推出独立种草社区平台:会不会成为第二个小红书

石头IT视角

架构实战营模块 6 作业

Roy

架构实战营

java零基础入门-Scanner类

喵手

Java’ 7月月更

张平安:加快云上数字创新,共建产业智慧生态

华为云开发者联盟

云计算 后端 SaaS 华为云

“去虚向实”大潮下,百度智能云向实而生

科技新知

Flutter3.0了,小程序不止于移动应用跨端运行

Speedoooo

flutter 小程序 移动开发 小程序容器 跨端运行

组织实战攻防演练的5个阶段

穿过生命散发芬芳

攻防演练 7月月更

牛客java选择题每日打卡Day8

京与旧铺

7月月更

谈谈讲清楚这件事的重要性

阿里巴巴中间件

阿里云 技术 云原生

一个酷酷的“幽灵”控制台工具

为自己带盐

C# 控制台 7月月更

小程序能运行在自有App中,且实现直播和连麦?

Speedoooo

小程序 直播 移动开发 小程序容器 连麦

用头像模仿天狗食月

急需上岸的小谢

7月月更

企业数字化转型,低代码是“趋势”还是“陷阱”?

云智慧AIOps社区

大前端 低代码 云开发

SchedulX V1.4.0及SaaS版发布,免费体验降本增效高级功能!

星汉未来

DevOps 运维 k8s IT FinOps

offer如何选择该考虑哪些因素

KEY.L

7月月更

阿里云中间件开源往事

阿里巴巴中间件

阿里云 开源 中间件

枚举通用接口&枚举使用规范

靠谱的程序员

枚举 企业应用 企业级应用

【写给初发论文的人】撰写综述性科技论文常见问题

左手の明天

论文阅读 论文 论文写作 研究论文 论文撰写

ServiceMesh主要解决的三大痛点

阿泽🧸

Service Mesh 7月月更

【愚公系列】2022年7月 Go教学课程 005-变量

愚公搬代码

7月月更

Salesforce 容器化 ISV 场景下的软件供应链安全落地实践

阿里巴巴中间件

阿里云 容器 云原生 安全

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