鸿蒙 hmdriver2:开启纯血鸿蒙 NEXT 自动化新时代

文摘   2024-10-19 12:48   四川  

作者介绍

matrixer,10年互联网行业测试开发经验,曾就职于腾讯,字节跳动,蚂蚁金服,一直从事移动端测试开发工作,对自动化测试有较深入的理解。

前言

写这个项目前github上已有个hmdirver,但它是侵入式(需要提前在手机端安装一个testRunner app)。另外鸿蒙官方提供的hypium自动化框架,使用较为复杂,依赖繁杂。于是决定重写一套。hmdriver2是一款支持HarmonyOS NEXT系统的UI自动化框架,无侵入式,提供应用管理,UI操作,元素定位等功能,轻量高效,上手简单,快速实现鸿蒙应用自动化测试需求。

设计思路

  • 无侵入式

    • 无需提前在手机端安装testRunner APP(类似atx app)

  • 易上手

    • 在PC端编写Python脚本实现自动化

    • 对齐Android端 uiautomator2 的脚本编写姿势

  • 轻量高效

    • 摒弃复杂依赖(几乎0依赖),即插即用

    • 操作响应快,低延时

  • 支持应用管理

    • 应用启动,停止

    • 应用安装,卸载

    • 应用数据清理

    • 获取应用列表,应用详情等

  • 支持设备操作

    • 获取设备信息,分辨率,旋转状态等

    • 屏幕解锁,亮屏,息屏

    • Key Events

    • 文件操作

    • 屏幕截图

    • 屏幕录屏

    • 手势操作(点击,滑动,输入,复杂手势)

  • 支持控件操作

    • 控件查找(联合查找,模糊查找,相对查找,xpath查找)

    • 控件信息获取

    • 控件点击,长按,拖拽,缩放

    • 文本输入,清除

    • 获取控件树

  • 支持Toast获取

  • UI Inspector

  • [TODO] 全场景弹窗处理

  • [TODO] 操作标记

UI inspector

UI 控件树可视化工具,查看控件树层级,获取控件详情。


快速上手

  1. 配置鸿蒙HDC环境(等价于 android 端的 adb)

    1. 下载 Command Line Tools 并解压

    2. hdc文件在command-line-tools/sdk/HarmonyOS-NEXT-DB2/openharmony/toolchains目录下

    3. 配置环境变量,macOS 为例,在~/.bash_profile 或者 ~/.zshrc 文件中添加

export HM_SDK_HOME="/Users/develop/command-line-tools/sdk/HarmonyOS-NEXT-DB2"  //请以sdk实际安装目录为准export PATH=$PATH:$HM_SDK_HOME/hms/toolchains:$HM_SDK_HOME/openharmony/toolchainsexport HDC_SERVER_PORT=7035

电脑插上手机,开启 USB 调试,确保执行hdc list targets 可以看到设备序列号。

安装hmdirver2 基础库

pip3 install -U hmdriver2

如果需要使用屏幕录屏 功能,则需要安装额外依opencv-python

pip3 install -U "hmdriver2[opencv-python]"// 由于`opencv-python`比较大,因此没有写入到主依赖中,按需安装


接下来就可以愉快的进行脚本开发了 😊😊

from hmdriver2.driver import Driverd = Driver("FMR0223C13000649")print(d.device_info)# ouput: DeviceInfo(productName='HUAWEI Mate 60 Pro', model='ALN-AL00', sdkVersion='12', sysVersion='ALN-AL00 5.0.0.60(SP12DEVC00E61R4P9log)', cpuAbi='arm64-v8a', wlanIp='172.31.125.111', displaySize=(1260, 2720), displayRotation=<DisplayRotation.ROTATION_0: 0>)d.start_app("com.kuaishou.hmapp", "EntryAbility")d(text="精选").click()...

功能介绍

应用管理

  • 应用启动,停止

  • 应用安装,卸载

  • 应用数据清理

  • 获取应用列表,应用详情等

代码示例

from hmdriver2.driver import Driver
d = Driver("FMR0223C13000649") # 替换成你的serial
d.install_app("/Users/develop/harmony_prj/demo.hap")
d.start_app("com.kuaishou.hmapp", "EntryAbility")
d.uninstall_app("com.kuaishou.hmapp")
d.stop_app("com.kuaishou.hmapp")
# 该方法表示清除App数据和缓存d.clear_app("com.kuaishou.hmapp")

设备操作

  • 获取设备信息,分辨率,旋转状态等

  • 屏幕解锁,亮屏,息屏

  • Key Events

  • 文件操作

  • 屏幕截图

  • 手势操作(点击,滑动,输入,复杂手势)

代码示例

from hmdriver2.proto import DeviceInfo
info: DeviceInfo = d.device_info# output:# DeviceInfo(productName='HUAWEI Mate 60 Pro', model='ALN-AL00', sdkVersion='12', sysVersion='ALN-AL00 5.0.0.60(SP12DEVC00E61R4P9log)', cpuAbi='arm64-v8a', wlanIp='172.31.125.111', displaySize=(1260, 2720), displayRotation=<DisplayRotation.ROTATION_0: 0>)
# 获取设备旋转状态rotation = d.display_rotation# ouput: DisplayRotation.ROTATION_0
# KeyEventd.press_key(KeyCode.POWER)
# 截图d.screenshot(""./test.png")

手势操作包括单击,双击,滑动,输入,复杂手势

d.click(200, 300)d.click(0.4, 0.6)d.double_click(500, 1000)d.swipe(0.5, 0.8, 0.5, 0.4, speed=2000)
d.gesture.start(x1, y1, interval=.5).move(x2, y2).pause(interval=1).move(x3, y3).action()

如下是一个复杂手势的效果展示

屏幕录屏

with d.screenrecord.start("test2.mp4"):    # do somethings    time.sleep(5)

通过上下文语法,在录屏结束时框架会自动调用stop 清理资源

控件操作

  • 控件查找(联合查找,模糊查找,相对查找)

  • 控件信息获取

  • 控件点击,长按,拖拽,缩放

  • 文本输入,清除

  • 获取控件树

控件查找支持这些by属性

  • id

  • key

  • text

  • type

  • description

  • clickable

  • longClickable

  • scrollable

  • enabled

  • focused

  • selected

  • checked

  • checkable

  • isBefore

  • isAfter

定位方式包括普通定位,模糊定位,相当定位

d(text="tab_recrod")
d(id="drag")
# 定位所有`type`为Button的元素,选中第0个d(type="Button", index=0)
# 定位`type`为Button且`text`为tab_recrod的元素d(type="Button", text="tab_recrod")
# 定位`text`为showToast的元素的前面一个元素d(text="showToast", isAfter=True)
# 定位`id`为drag的元素的后面一个元素d(id="drag", isBefore=True)

定位到控件后就可以进行信息获取和控件操作了

from hmdriver2.proto import ComponentData
d(text="tab_recrod").info
# output:{ "id": "", "key": "", "type": "Button", "text": "tab_recrod", "description": "", "isSelected": False, "isChecked": False, "isEnabled": True, "isFocused": False, "isCheckable": False, "isClickable": True, "isLongClickable": False, "isScrollable": False, "bounds": { "left": 539, "top": 1282, "right": 832, "bottom": 1412 }, "boundsCenter": { "x": 685, "y": 1347 }}
d(text="tab_recrod").click()d(type="Button", text="tab_recrod").click()
d(text="tab_recrod").click_if_exists()
d(text="tab_recrod").double_click()d(text="tab_recrod").long_click()
# 控件拖拽componentB: ComponentData = d(type="ListItem", index=1).find_component()d(type="ListItem").drag_to(componentB) # 将元素拖动到元素B上
# 控件缩放d(text="tab_recrod").pinch_in(scale=0.5)d(text="tab_recrod").pinch_out(scale=2)

Toast 获取

hmdriver2 还可以获取界面的 toast,用法如下

# 启动toast监控d.toast_watcher.start()
# do something 比如触发toast的操作d(text="xx").click()
# 获取toasttoast = d.toast_watcher.get_toast()
# output: 'testMessage'

PS. 所有功能详细介绍可以查看 API 文档

API 文档

https://github.com/codematrixer/hmdriver2/tree/master#api-documents

后续计划

  • [TODO] 全场景弹窗处理

  • [TODO] 操作标记

  • [TODO] Inspector

软件质量保障
所寫即所思|一个阿里质量人对测试技术的思考。
 最新文章