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

微信交流群(永久生效)
<img src="https://i.ibb.co/Xx9HcKk/wechat.png" alt="wechat" style="float: left" />Key idea
- 无侵入式
- 无需提前在手机端安装testRunner APP(类似atx app)
- 易上手
- 在PC端编写Python脚本实现自动化
- 对齐Android端 uiautomator2 的脚本编写姿势
- 轻量高效
- 摒弃复杂依赖(几乎0依赖),即插即用
- 操作响应快,低延时
Feature
- 支持应用管理
- 应用启动,停止
- 应用安装,卸载
- 应用数据清理
- 获取应用列表,应用详情等
- 支持设备操作
- 获取设备信息,分辨率,旋转状态等
- 屏幕解锁,亮屏,息屏
- Key Events
- 文件操作
- 屏幕截图
- 屏幕录屏
- 手势操作(点击,滑动,输入,复杂手势)
- 支持控件操作
- 控件查找(联合查找,模糊查找,相对查找,xpath查找)
- 控件信息获取
- 控件点击,长按,拖拽,缩放
- 文本输入,清除
- 获取控件树
- 支持Toast获取
- UI Inspector
- [TODO] 全场景弹窗处理
- [TODO] 操作标记
QUICK START
- 配置鸿蒙
HDC环境- 下载 Command Line Tools 并解压
hdc文件在command-line-tools/sdk/default/openharmony/toolchains目录下- 配置环境变量,macOS为例,在~/.bash_profile 或者 ~/.zshrc文件中添加
export HM_SDK_HOME="/Users/develop/command-line-tools/sdk/default" //请以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
(由于opencv-python比较大,因此没有写入到主依赖中,按需安装)
pip3 install -U "hmdriver2[opencv-python]"
- 接下来就可以愉快的进行脚本开发了 😊😊
from hmdriver2.driver import Driver
d = Driver()
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")
d(text="精选").click()
d.swipe(0.5, 0.8, 0.5, 0.4)
...
UI inspector
UI 控件树可视化工具,查看控件树层级,获取控件详情。

详细介绍请看 ui-viewer
Environment
如何需要连接远端的HDC Server来实现操作远端设备执行自动化,运行脚本前需要设置环境变量
export HDC_SERVER_HOST=127.0.0.1 # Replace with the remote host
export HDC_SERVER_PORT=8710
PS 如果需要移除环境变量,执行以下命令
unset HDC_SERVER_HOST
unset HDC_SERVER_PORT
API Documents
初始化Driver
from hmdriver2.driver import Driver
d = Driver()
# d = Driver("FMR0223C13000649")
参数serial 通过hdc list targets 命令获取;如果不传serial,则默认读取hdc list targets的第一个设备
初始化driver后,下面所有的操作都是调用dirver实现
App管理
安装App
d.install_app("/Users/develop/harmony_prj/demo.hap")
卸载App
d.uninstall_app("com.kuaishou.hmapp")
传入的参数是package_name,可通过hdc命令获取hdc shell bm dump -a
启动App
d.start_app("com.kuaishou.hmapp")
d.start_app("com.kuaishou.hmapp", "EntryAbility")
package_name, page_name分别为包名和ability name,可以通过hdc命令获取:hdc shell aa dump -l
不传page_name时,默认会使用main ability作为page_name
停止App
d.stop_app("com.kuaishou.hmapp")
清除App数据
d.clear_app("com.kuaishou.hmapp")
该方法表示清除App数据和缓存
获取App详情
d.get_app_info("com.kuaishou.hmapp")
输出的数据结构是Dict, 内容如下
{
"appId": "com.kuaishou.hmapp_BIS88rItfUAk+V9Y4WZp2HgIZ/JeOgvEBkwgB/YyrKiwrWhje9Xn2F6Q7WKFVM22RdIR4vFsG14A7ombgQmIIxU=",
"appIdentifier": "5765880207853819885",
"applicationInfo": {
...
"bundleName": "com.kuaishou.hmapp",
"codePath": "/data/app/el1/bundle/public/com.kuaishou.hmapp",
"compileSdkType": "HarmonyOS",
"compileSdkVersion": "4.1.0.73",
"cpuAbi": "arm64-v8a",
"deviceId": "PHONE-001",
...
"vendor": "快手",
"versionCode": 999999,
"versionName": "12.2.40"
},
"compatibleVersion": 40100011,
"cpuAbi": "",
"hapModuleInfos": [
...
],
"reqPermissions": [
"ohos.permission.ACCELEROMETER",
"ohos.permission.GET_NETWORK_INFO",
"ohos.permission.GET_WIFI_INFO",
"ohos.permission.INTERNET",
...
],
...
"vendor": "快手",
"versionCode": 999999,
"versionName": "12.2.40"
}
获取App main ability
d.get_app_main_ability("com.kuaishou.hmapp")
输出的数据结构是Dict, 内容如下
{
"name": "EntryAbility",
"moduleName": "kwai",
"moduleMainAbility": "EntryAbility",
"mainModule": "kwai",
"isLauncherAbility": true,
"score": 2
}
设备操作
获取设备信息
from hmdriver2.proto import DeviceInfo
info: DeviceInfo = d.device_info
输入内容如下
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>)
然后就可以获取你想要的值, 比如
info.productName
info.model
info.wlanIp
info.sdkVersion
info.sysVersion
info.cpuAbi
info.displaySize
info.displayRotation
获取设备分辨率
w, h = d.display_size
# outout: (1260, 2720)
获取设备旋转状态
from hmdriver2.proto import DisplayRotation
rotation = d.display_rotation
# ouput: DisplayRotation.ROTATION_0
设备旋转状态包括:
ROTATION_0 = 0 # 未旋转
ROTATION_90 = 1 # 顺时针旋转90度
ROTATION_180 = 2 # 顺时针旋转180度
ROTATION_270 = 3 # 顺时针旋转270度
设置设备旋转
from hmdriver2.proto import DisplayRotation
# 旋转180度
d.set_display_rotation(DisplayRotation.ROTATION_180)
Home
d.go_home()
返回
d.go_back()
亮屏
d.screen_on()
息屏
d.screen_off()
屏幕解锁
d.unlock()
Key Events
from hmdriver2.proto import KeyCode
d.press_key(KeyCode.POWER)
详细的Key code请参考 harmony key code
执行 HDC 命令
data = d.shell("ls -l /data/local/tmp")
print(data.output)
这个方法等价于执行 hdc shell ls -l /data/local/tmp
Notes: HDC详细的命令解释参考:awesome-hdc
打开URL (schema)
d.open_url("http://www.baidu.com")
d.open_url("kwai://myprofile")
文件操作
# 将手机端文件下载到本地电脑
d.pull_file(rpath, lpath)
# 将本地电脑文件推送到手机端
d.push_file(lpath, rpath)
参数rpath表示手机端文件路径,lpath表示本地电脑文件路径
屏幕截图
d.screenshot(path)
参数path表示截图保存在本地电脑的文件路径
屏幕录屏
方式一
# 开启录屏
d.screenrecord.start("test.mp4")
# do somethings
time.sleep(5)
# 结束录屏
d.screenrecord.stop()
上述方式如果录屏过程中,脚本出现异常时,stop无法被调用,导致资源泄漏,需要加上try catch
【推荐】方式二 ⭐️⭐️⭐️⭐️⭐️
with d.screenrecord.start("test2.mp4"):
# do somethings
time.sleep(5)
通过上下文语法,在录屏结束时框架会自动调用stop 清理资源
Notes: 使用屏幕录屏需要依赖opencv-python
pip3 install -U "hmdriver[opencv-python]"
Device Touch
单击
d.click(x, y)
# eg.
d.click(200, 300)
d.click(0.4, 0.6)
参数x, y表示点击的坐标,可以为绝对坐标值,也可以为相当坐标(屏幕百分比)
双击
d.double_click(x, y)
# eg.
d.double_click(500, 1000)
d.double_click(0.5, 0.4)
长按
d.long_click(x, y)
# eg.
d.long_click(500, 1000)
d.long_click(0.5, 0.4)
滑动
d.swipe(x1, y1, x2, y2, spped)
# eg.
d.swipe(600, 2600, 600, 1200, speed=2000) # 上滑
d.swipe(0.5, 0.8, 0.5, 0.4, speed=2000)
x1,y1表示滑动的起始点,x2,y2表示滑动的终点speed为滑动速率, 范围:200~40000, 不在范围内设为默认值为2000, 单位: 像素点/秒
滑动 ext
d.swipe_ext("up") # 向上滑动,"left", "right", "up", "down"
d.swipe_ext("right", scale=0.8) # 向右滑动,滑动距离为屏幕宽度的80%
d.swipe_ext("up", box=(0.2, 0.2, 0.8, 0.8)) # 在屏幕 (0.2, 0.2) -> (0.8, 0.8) 这个区域上滑
# 使用枚举作为参数
from hmdriver2.proto import SwipeDirection
d.swipe_ext(SwipeDirection.DOWN) # 向下滑动
direction表示滑动方向,可以为up,down,left,right, 也可以为SwipeDirection的枚举值scale表示滑动距离百分比,范围:0.1~1.0, 默认值为0.8box表示滑动区域,格式为(x1, y1, x2, y2), 表示滑动区域的左上角和右下角的坐标,可以为绝对坐标值,也可以为相当坐标(屏幕百分比)
Notes: swipe_ext和swipe的区别在于swipe_ext可以指定滑动区域,并且可以指定滑动方向,更简洁灵活
复杂手势
复杂手势就是手指按下start,移动move,暂停pause的集合,最后运行`acti
Related Skills
imsg
337.3kiMessage/SMS CLI for listing chats, history, and sending messages via Messages.app.
node-connect
337.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
oracle
337.3kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
lobster
337.3kLobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (s
