作者介绍
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 控件树可视化工具,查看控件树层级,获取控件详情。
快速上手
配置鸿蒙
HDC
环境(等价于 android 端的 adb)下载 Command Line Tools 并解压
hdc
文件在command-line-tools/sdk/HarmonyOS-NEXT-DB2/openharmony/toolchains目录下
配置环境变量,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/toolchains
export 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 Driver
d = 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
# KeyEvent
d.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()
# 获取toast
toast = d.toast_watcher.get_toast()
# output: 'testMessage'
PS. 所有功能详细介绍可以查看 API 文档
API 文档
https://github.com/codematrixer/hmdriver2/tree/master#api-documents
后续计划
[TODO] 全场景弹窗处理
[TODO] 操作标记
[TODO] Inspector