技术联盟2021-06-03 13:08
(资料图片仅供参考)
小工匠捕鱼技术
Flutter page不能直接使用原生测试工具定位元素,给自动化测试带来很多不便。虽然Google官方推出了Flutter驱动和集成测试,但实际使用中存在以下问题:
不适用于混合堆栈app。虽然appium里有相关驱动,但是环境不能切换。
元素定位能力比较弱。
根据VMService,您需要构建配置文件或调试包。
基于以上因素,我们没有直接使用Google官方推出的工具,而是选择在原生测试工具的基础上扩展Flutter page的测试能力。本文分析了颤振驱动和集成测试的原理和实现,并简要介绍了free fish在UI自动化测试中的尝试方案。
颤动驱动器
我之一次接触flutter自动化测试的时候,之一次尝试用APPium框架驱动app。当我们使用inspect函数转储页面元素时,我们发现很多元素会被合并成一个区域块,然后点击时只能通过xpath定位。定位某些特定元素会很困难,而xpath实际上很容易更改,所以代码可维护性很差。
因为以上原因,我们开始调查——flutter提供的官方测试工具flutter driver。刚开始使用这个框架时,发现它只能应用于纯颤振应用,而不能应用于混合栈应用。但是,它的底层提供的元素定位能力可能对我们有用,所以我们分析了它的源代码。该框架的示意图如下所示。
图1颤振驱动器原理图
整个框架的流程交互比较简单。测试脚本运行时,首先使用FlutterDriver.connect()连接VMService获取相关隔离,然后通过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混合栈应用的测试需求。最终的实现代码演示如下。
fromflutter_driver.finderimportFlutterFinderfromflutter_driver.flutter_driverimportFlutterDriverimportuiautomator2asu2if__name__=="__main__":d=u2.connect()driver=FlutterDriver(d)ifpageFlutterisTrue:#如果是flutter,则使用flutterdriver进行驱动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找到多个元素,它将抛出一个异常。
很多时候开发生不写key,元素定位也没那么方便。
由于flutter没有inspect tool dump元素,只能使用组合的源代码编写脚本,代码维护成本相对较高。
官方已经放弃了这个项目的维护,所以后续估计不会有新的功能支持了。
集成_测试
如前所述,flutter官方放弃维护Flutter驱动,引入了新的测试框架integration_test。那么这个框架会支持混合栈应用吗?其实试过之后发现,事情并没有我们想象的那么美好。官方文件中有这样一句话“这个软件包可以在设备和模拟器上自驾测试颤振代码”。
integration_test底层元素的操作和定位由flutter_test驱动,其优点如下:
测试脚本可以使用各种Flutter APIs。
在打包ipa和apk之后,您可以在Firebase Test Lab和其他设备组上运行测试,而不需要额外的驱动程序。
integration_test的各个页面之间没有关联,因此可以实现单页面级别的测试。
然而,因为基础元件的定位与颤振驱动器的定位是一致的,所以颤振驱动器的问题仍然存在,并且存在其他限制:
测试脚本打包到APP中,每次修改脚本都需要重新打包。
端到端测试不够友好,需要额外的功能等待数据加载。
不适合全链接级页面测试。
弱可扩展性
基于以上问题,不符合我们的使用要求,所以我们只是做了简单的预研,没有深入的了解和应用。
闲鱼UI的自动化测试方案
在学习了Flutter官方推出的相关测试框架后,我们开始思考如何将闲鱼的UI自动化。是在官方的肩膀上造一个轮子,还是重用现有的原生自动化测试能力来扩展颤振测试能力。在考虑投资成本和维护测试脚本的难度后,我们选择使用图像处理技术来扩展native automation框架对Flutter页面的测试能力支持。整个测试方案架构如图2所示。
图2闲鱼UI自动化测试方案架构
uiautomator2和facebook-wda并不是完全无法识别Flutter的元素,所以你只需要在编写测试脚本的时候处理无法识别的元素。对于名字、标签、xpath不易更改的元素,我们优先使用原生本地化能力进行本地化操作,其他元素直接使用图像处理技术进行本地化。
在处理原生能力无法定位的元素时,我们优先采用ocr文本匹配来定位,准确率高,不易受分辨率影响。对于纯图片,我们通过图片搜索来定位。对于一些常见的元素控件,如商品卡、价格、图标、头像等。构建训练集,利用图像分类来判断元素的类型,从而实现常见控件的定位。
UI自动化面临的更大问题是,随着版本的迭代,测试脚本也需要不断迭代。因此,在方案选择和脚本编写过程中,要考虑脚本的健壮性和可维护性。在实际的脚本开发中,我们将页面元素封装到单独的类中,并与测试逻辑分离,从而保证在元素的后期迭代中只需要修改对应的页面元素,降低了维护成本。
图3脚本层次结构
这个方案已经被用于与自动测试idle fish性能相关的UI操作。写脚本的时候,不需要区分当前页面是什么类型。我们的脚本已经稳定运行了500+次,成功率超过98%。
摘要
图4方案比较
从图4可以看出,颤振驱动和集成测试都还不够成熟,不足以支持混合栈,但是颤振驱动可以做一些扩展。对于纯颤振应用,这种方案基本可以满足测试要求,而综合测试还没有那么成熟。对于混合堆栈应用的测试,可能仍然需要考虑混合堆栈的场景切换成本。用一些ocr技术做一些扩展,可能成本更低,收益更大。
表示感谢/感激
感谢SLM和TMQ的支持,我们可以专注于我们的业务。
flutter驱动(https://flutter . dev/docs/cookbook/testing/integration/introduction)
integration _ test(https://flutter . dev/docs/testing/integration-tests)
收集0条评论。
关键词: 测试工具