做移动端自动化测试的朋友,应该都有过这样的经历:电脑上装好了Appium,跑安卓模拟器跑得飞起,结果拿到一台华为鸿蒙手机,一连接就各种报错。要么是设备列表里看不到手机,要么是Appium Inspector死活拉不起应用,要么是跑脚本的时候一直超时。我以前也以为鸿蒙和安卓差不多,直接照着安卓的配置来就行,结果踩了一堆坑。
后来我专门花了一个下午,从零开始把Appium针对华为鸿蒙手机的自动化测试环境完整配了一遍,把中间的弯路、报错、驱动冲突都记录了下来。这篇文章就是给你梳理一份可以直接照着做的完整配置指南,涵盖基础软件准备、hdc工具链、鸿蒙应用的元素定位、以及几个高频疑难问题的处理思路。不管你是刚接触鸿蒙自动化,还是已经在安卓环境上吃了很多年经验、现在想扩展鸿蒙设备,都能在这篇文章里找到你需要的答案。
1. 项目核心需求解析与环境规划
1.1 先搞明白:鸿蒙设备的自动化到底是怎么回事
在动手配置之前,有个概念必须得梳理清楚。很多人一上来就搜“鸿蒙自动化”,搜出一堆开源鸿蒙(OpenHarmony)的测试框架,然后就开始安装各种包,最后发现和自己手上的华为手机完全对不上。问题出在,手机上的HarmonyOS和开源鸿蒙系统并不是一回事。
目前市面上能买到的华为手机、平板,搭载的是HarmonyOS。其中早期的HarmonyOS 2/3/4版本,底层保留了对安卓应用兼容的能力,也就是说,即使系统是鸿蒙,它依然可以安装和运行APK格式的安卓应用。这类设备,Appium在原理上依然是通过安卓的调试通道(ADB)来驱动的,只是华为在设备连接和权限细节上加入了自己的实现,所以需要额外的工具链支持。
而最新的HarmonyOS NEXT(也就是常说的“纯血鸿蒙”),砍掉了安卓兼容层,只能安装HAP格式的原生鸿蒙应用。这类设备,传统Appium加安卓驱动的方案是跑不通的,需要走华为官方提供的测试框架和Appium扩展。
所以,在配置环境之前,你第一件事应该是确认你手上的设备型号和系统版本。举个例子:
- 华为Mate 40 Pro,设置里显示HarmonyOS 4.0,说明是可兼容安卓应用的鸿蒙设备。
- 华为Pura 70系列,如果升级到了HarmonyOS NEXT,那就是纯血鸿蒙设备。
对于绝大多数还在搞自动化测试的朋友来说,手上的鸿蒙设备往往还是兼容安卓应用的版本,这种场景下用Appium比较顺手,也是这篇文章重点讲的环境配置方案。如果你公司有专门的鸿蒙原生测试团队,那需要对接的是华为的CloudDevEco测试服务,配置路径完全不同,就不在这篇文章里展开了。
1.2 明确技术选型:为什么选择Appium作为自动化框架
Appium本身是一个跨平台的自动化测试框架,它通过WebDriver协议向下屏蔽了不同平台的差异,向上给测试代码提供了一套统一的API。无论你是用Java写、Python写,还是用JavaScript写,都可以通过这套API控制手机上的应用做点击、滑动、输入等操作。鸿蒙手机在兼容安卓应用的前提下,Appium会自动走Android的自动化驱动,这一点极大降低了上手门槛。
从测试工程的角度选型,Appium还有几个实在的好处:
- 社区活跃度足够高,网上随手就能搜到各种问题的解决方案,不像某些商业测试框架出了问题只能提工单。
- 支持的语言多样,团队里不管谁会哪种语言,都能很快写出测试脚本。
- 它本身是C/S架构,测试脚本在电脑上跑,手机只负责接收指令执行,不会像某些框架那样需要在手机上装一个臃肿的Agent。
当然,Appium也不是没有缺点。最大的问题就在于环境配置比较繁琐,尤其是国内网络环境下,下载依赖、安装驱动、连接设备都可能出幺蛾子。这篇文章存在的意义,就是把这些坑提前帮你踩一遍。
1.3 环境规划的整体思维导图
按我这个思路,你整个环境配置过程可以拆成这么几层:
- 基础运行时:Java和Node.js。Appium是Node.js服务,而安卓驱动工具链依赖Java。
- 设备连接层:华为hdc工具,相当于安卓的adb,用于电脑和鸿蒙手机通信。
- 自动化服务层:Appium Server及Appium Inspector。
- 测试代码层:一个简单的Python示例脚本,用于验证整个链路通不通。
理解这个分层逻辑之后,你配置的时候就不会慌了。每一步解决一层问题,遇到报错时,你能快速定位是哪个环节出了问题,而不至于把所有锅都甩给Appium。
2. 环境配置前的准备与版本选型
2.1 基础软件安装:Java与Node.js的环境要求
Appium从2.0版本开始,对Node.js的版本要求比较严格。我最初用的是Node.js 12的老版本,安装Appium的时候直接提示“当前Node版本不受支持”,后来换成了Node.js 16 LTS版本才顺利通过。这里建议你装Node.js 16或18的稳定版,具体版本号不用太纠结,LTS就行。安装的时候注意勾选“Add to PATH”选项,不然后面在命令行里执行node命令会提示找不到。
Java这边要装JDK,版本建议8以上。华为hdc工具本身不强制要求Java,但Appium的安卓驱动在解析应用信息、生成测试报告时,可能会用到Java相关工具链。更关键的是,如果你后面要接华为的调试服务或者使用某些自动化辅助工具,没有Java环境会寸步难行。我装的是JDK 8,碰到的问题最少。有人用JDK 17也跑通了,但如果你的项目里没有其他强制要求,JDK 8够用且稳定。
安装完成后,老规矩,在终端里验证一下:
node -v java -version如果命令能正常输出版本号,说明基础环境没问题,可以进行下一步。
2.2 华为hdc工具链的全流程安装
这是鸿蒙设备配置过程中最容易有陌生感的地方。hdc,全称是HarmonyOS Device Connector,是华为为鸿蒙设备提供的调试工具,类似安卓的adb。Appium要控制华为手机,底层必须通过这个工具跟设备建立连接。
hdc工具一般有两个来源:一是安装了DevEco Studio之后,在它的SDK目录里能找到;二是从华为开发者官网的“命令行工具”页面下载独立版本。如果你只是做Appium测试,不需要写鸿蒙应用,那没有必要装几个G的DevEco Studio,直接下载独立版hdc就够了。
下载之后是个压缩包,解压到你想要的目录,比如D:\hdc-tool。然后把该目录路径加到系统的PATH环境变量里。这一步很多人会忘记,导致后面执行hdc命令时提示“无法识别”。
配置好PATH后,打开命令行窗口,输入:
hdc -v能输出版本号,说明工具安装成功。鸿蒙手机上需要先开启“开发者模式”:连续点击“关于手机”里的软件版本号7次,然后在“系统和更新”里找到“开发人员选项”,把“USB调试”开关打开。这里有个华为特有的细节,在开发人员选项里还有一个“仅充电模式下允许ADB调试”的选项,如果这个不打开,手机连上电脑后只显示充电,无法进行自动化调试。不同型号、不同系统的设置位置可能有差异,但你按这个思路找,基本不会差太远。
2.3 手机连接前的准备工作
手机连接电脑这个环节,建议你提前做好三件事,能省去后面一堆麻烦:
- 确认USB数据线是支持数据传输的,而不是那种只能充电的线。很多初学者找了半天原因,最后发现是线不行。
- 手机插上电脑后,下拉通知栏,把USB连接模式从“仅充电”改成“传输文件”。如果不改,某些系统版本下hdc会识别不到设备。
- 如果之前连接过其他设备,最好先重启一下手机和电脑的调试服务,清理端口占用。
现在的华为手机,插上数据线后一般会自动安装驱动。如果你的电脑第一次连华为手机且一直提示驱动安装失败,可以去华为官网下载华为手机助手或者Hisuite,安装过程中会自动把手机驱动一并装上。
3. Appium服务端与驱动的安装
3.1 全局安装Appium 2.0
Appium从2.0版本开始,架构上做了比较大的调整,原来的安卓驱动(UIAutomator2)不再默认包含在Appium里,而是需要单独安装。这算是个好事,因为它让Appium的核心变得更轻量,但也意味着你装完Appium之后,还要多执行一条命令来装驱动。
我用npm全局安装Appium:
npm install -g appium@2安装完之后,验证一下版本:
appium -v能输出2.x的版本号就OK。
接着安装安卓驱动:
appium driver install uiautomator2这个命令会从远程仓库下载UIAutomator2驱动及相关依赖。如果你在下载过程中卡住或者一直超时,那大概率是网络问题。可以换成国内镜像源后再试一次。npm镜像切换的方法如下:
npm config set registry https://registry.npmmirror.com切换完镜像重新安装即可。驱动安装成功后,可以用下面的命令查看已安装的驱动列表:
appium driver list3.2 在桌面端启动Appium服务
Appium安装好之后,有两种方式启动服务。一种是直接在命令行启动:输入appium,然后回车,服务就会默认在4723端口开启。另一种是在测试代码里通过代码方式动态启动服务,适合后面做CI集成。
我个人习惯是先用命令行方式启动,因为这样日志输出比较直观。启动成功之后,你会看到类似这样的输出:
[Appium] Welcome to Appium v2.x.x [Appium] Appium REST http interface listener started on 0.0.0.0:4723这个信息说明Appium服务已经正常启动,等待测试代码来连接了。
3.3 配置Appium Inspector进行元素定位
Appium Inspector是Appium生态里的元素检查工具,能帮你在手机上实时查看当前界面的布局结构、控件属性,是写自动化脚本的利器。鸿蒙手机上,因为走的是安卓兼容层,所以Inspectgor的用法和安卓设备几乎一模一样。
Inspector现在不需要单独下载安装包,它是通过桌面应用方式运行的。你可以在Appium官网下载对应的桌面版本,也可以直接通过npm安装。
用Inspector连接鸿蒙手机时,需要在“Remote Path”里填上/wd/hub,端口是4723,Desired Capabilities里填上之前准备好的设备参数。连接成功后,你会看到手机屏幕的实时截图,左侧是界面结构树,右侧是控件属性列表。
用这个工具,我可以快速获取任意控件的resource-id,text,class等属性,然后直接填到测试脚本里作为定位依据。这是我每次做App自动化测试都会用到的功能,没有它纯粹靠猜测元素属性写脚本,效率会低很多。
3.4 鸿蒙系统版本与Appium驱动的兼容性问题
华为鸿蒙系统在持续迭代过程中,对安卓调试协议的兼容性也发生了一些变化。早期HarmonyOS 2.0阶段,hdc和adb的指令兼容做得比较好,直接用adb命令也能控制设备。到了HarmonyOS 3.0之后,华为逐渐弱化了adb通道,更加推崇使用hdc,导致一些老版本Appium驱动在鸿蒙设备上失效。
我实际遇到的情况是,在HarmonyOS 4.0的设备上,UIAutomator2驱动如果版本过低,启动应用时会报io.appium.settings无法安装的错误。解决方法是把驱动升级到最新版本:
appium driver update uiautomator2如果升级驱动之后问题依然存在,还给华为设备的开发者选项里把“USB调试(安全设置)”也打开,允许通过USB调试修改权限或模拟点击。这个选项在部分华为手机上默认是关闭的,如果不打开,自动化脚本执行到一半可能会因为权限不足而中断。
4. 鸿蒙手机与Appium的连接配置实操
4.1 使用hdc确认设备连接状态
设备连接是整个链路里最容易出问题的一环,所以我建议你在启动Appium之前,先用hdc确认设备列表,明确设备已经正常连接:
hdc list targets如果输出结果里有一串设备序列号,说明设备已被识别。如果提示“Empty”,那说明手机和电脑之间还没有建立连接,需要检查USB线、调试模式是否打开。如果有多台设备连接,后面配置Capabilities时要指定具体的udid,否则Appium会报“多个设备无法选择”的错误。
连接正常之后,还可以用它获取手机的型号和鸿蒙系统版本,方便后面填参数。
除了通过USB连接,hdc还支持WiFi无线连接。对有无线调试需求的朋友,这点也值得了解一下,因为在实际测试过程中,经常需要同时在多台设备上跑测试,这时候全部靠数据线连接就不太方便了。hdc无线连接的方式,我是通过先USB连接设备,然后执行以下命令开启无线调试端口,之后再拔掉数据线,用网络连接来调试设备。具体的hdc命令,你可以在命令行输入hdc help查阅。
4.2 获取鸿蒙手机的应用包名与主Activity
配置Desired Capabilities的时候,需要指定应用包名(appPackage)和主Activity(appActivity)。在鸿蒙手机上获取这两个参数的方式,和安卓设备基本一致。我经常用的有两种方式:
第一种,通过hdc命令直接查看当前正在运行的应用包名:
hdc shell "param get const.product.software.version"这个命令能获取系统版本。获取前台应用包名,可以执行:
hdc shell uiautomator dump然后查看生成的XML文件。
第二种,安装应用后用Appium Inspector直接连接并检查,先把appPackage填成目标应用的包名,appActivity留空,连接成功之后,Appium会自动解析当前界面的Activity名称。这个方法不用记命令,对初学者比较友好。
如果你的应用是APK格式,还可以用aapt工具快速获取包名和Activity信息。hdc工具包里自带了一个类似功能的工具,名字叫aa。在命令行里执行:
hdc shell aa dump -l能列出当前系统的Activity栈信息。
4.3 配置Desired Capabilities参数
Appium连接设备时,通过Desired Capabilities来声明期望的能力。针对鸿蒙手机,我这里提供一个我实测过的推荐配置模板:
{ "platformName": "Android", "deviceName": "HuaweiMate40Pro", "platformVersion": "12", "appPackage": "com.example.app", "appActivity": ".MainActivity", "noReset": true, "unicodeKeyboard": true, "resetKeyboard": true, "automationName": "UiAutomator2", "udid": "你的设备序列号" }有几个参数需要注意:
platformName填Android,不要填HarmonyOS。因为Appium目前没有单独的HarmonyOS平台定义,在兼容安卓应用的鸿蒙设备上填Android才能正确走安卓驱动通道。填HarmonyOS的话,Appium会找不到对应的驱动,直接报错。automationName填UiAutomator2,代表使用UIAutomator2驱动。noReset设为true,避免每次跑测试都重置应用数据。如果要做干净的测试环境,再改成false。unicodeKeyboard和resetKeyboard建议都设为true,避免中文输入时遇到键盘弹不出来的问题。
4.4 在测试代码里启动Appium会话
配置好Capabilities之后,就可以写测试代码来验证连接了。我用Python写的验证脚本,代码很简单:
from appium import webdriver desired_caps = { "platformName": "Android", "deviceName": "HuaweiMate40Pro", "appPackage": "com.example.app", "appActivity": ".MainActivity", "noReset": True, "automationName": "UiAutomator2", "udid": "你的设备序列号" } driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps) print(driver.current_package) print(driver.current_activity) driver.quit()如果你能看到终端输出了软件包名和Activity名,说明Appium连接鸿蒙手机成功,自动化环境已经全面打通。
5. 常见问题与排查技巧实录
5.1 设备识别不了或连接不稳定
鸿蒙手机无法被电脑识别,是最常见的初级问题。排查顺序我建议如下:
- 换一根确认可以传数据的USB线。
- 打开手机开发者选项,关掉“仅充电模式下允许ADB调试”开关。
- 重启hdc服务:执行
hdc kill和hdc start。 - 检查设备管理器里有没有识别到“Android Composite ADB Interface”,如果没有,说明驱动没装好,需要手动更新驱动。
我遇到过一个比较隐蔽的问题:笔记本电脑的USB口供电不足,导致手机连接上后反复断开重连。后来换了一个USB口,问题立刻消失。
5.2 Appium Inspector无法连接到设备
Inspector连接手机失败,通常有两种情况。一种是Appium服务没有启动,启动着的话Inspector的“Start Session”按钮就不会生效。另一种是Capabilities参数不对,尤其是platformName填了HarmonyOS或者udid填错了。
还有一种特殊情况:如果手机锁屏了或者屏幕熄灭了,Inspector连接时可能拿不到界面信息。建议在开发者选项里打开“屏幕常亮”功能,或者连接前手动唤醒手机屏幕并解锁。
5.3 脚本执行时报错找不到元素
Appium脚本跑起来后报“An element could not be located”,这类问题大多数情况下不是环境问题,而是元素定位策略不对。鸿蒙手机上有一些应用是基于自研UI框架开发的,控件属性可能没有标准的resource-id,导致用id定位不到。
这种情况下,我的建议是:
- 优先用text文本定位,对中文应用支持比较稳定。
- 使用XPath定位,但要写相对简洁的表达式,避免复杂层级导致性能问题。
- 查看界面结构树,确认元素在当前的层级中是否可见。有些元素需要滚动才能显示。
5.4 应用启动后立即闪退
应用闪退的原因很多,最常见的是appActivity配置不对,导致应用启动后找不到指定的Activity。建议先手动打开应用,然后用hdc命令查询当前的Activity名,再填到配置里。
也有可能是应用本身就存在启动崩溃的问题,这和自动化环境无关,需要开发人员处理。
5.5 多个设备同时连接时的干扰问题
测试机多的时候,一台电脑同时控制多台鸿蒙手机是常事。这种情况下,如果每台设备上的Appium配置都是一样的,执行脚本时会相互干扰。解决方法有两个:一是在Capabilities里指定不同的udid,二是在启动Appium时使用不同的端口号。我一般是每台设备配一套Appium服务,所有设备用同一个脚本分别跑,测试效率能提高不少。
5.6 常见问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| hdc list targets为空 | USB调试未开启或驱动问题 | 检查开发者选项,重装驱动,换USB口 |
| Inspector无法连接 | Appium服务未启动或Capabilities错误 | 确认Appium在4723端口监听,检查参数配置 |
| Appium启动会话超时 | UIAutomator2驱动版本太低 | 执行appium driver update uiautomator2 |
| 中文输入失败 | 键盘设置不对 | 配置unicodeKeyboard和resetKeyboard为true |
| 应用闪退 | appActivity配置错误 | 查询真实Activity,注意大小写和前缀 |
| 设备断连 | USB线通讯不稳定 | 换线、换口,或用hdc无线连接 |
5.7 端口占用问题
Appium默认监听4723端口,如果这个端口被其他程序占用了,启动服务时会报错“端口被占用”。在Windows上,你可以用以下命令查看端口占用情况:
netstat -ano | findstr 4723找到占用进程的PID,然后在任务管理器里结束对应进程,或者直接换一个端口启动Appium:
appium -p 4724如果用了非默认端口,意味着你的测试代码里远程连接地址也要改成对应的端口号。
6. 实操验证与效果测试
6.1 跑通第一个鸿蒙设备上的自动化脚本
环境配置完成之后,我习惯先跑一个最简单的脚本验证全链路。下面是一个示例,实现打开一个应用,然后等待几秒钟后关闭它:
import time from appium import webdriver desired_caps = { "platformName": "Android", "deviceName": "HuaweiP40", "appPackage": "com.huawei.camera", "appActivity": ".Camera", "noReset": True, "automationName": "UiAutomator2" } driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps) time.sleep(5) driver.quit()这个脚本如果能在真实设备上正常打开相机应用,说明环境配置没有问题,后续的测试脚本都可以基于这套环境来扩展了。
6.2 实战中的性能调优建议
环境通了之后,如果你想把这套方案真正用到实际项目中,有几个性能调优的点值得一提:
- Appium服务启动参数加上
--relaxed-security,可以在某些场景下减少安全校验导致的延迟。 - 脚本中使用显式等待代替固定延时,比如
WebDriverWait配合expected_conditions,能显著提高脚本稳定性。 - 如果测试用例多,建议用pytest或TestNG做用例管理,不要全都写在同一个脚本文件里。
- 尽量减少在测试脚本里做大量数据计算,这些操作放在服务端执行,能够降低手机端的功耗和响应延迟。
6.3 集成到CI流水线中的环境准备
如果说你不想只在本地跑脚本,还想把这套环境配置用到公司的持续集成流水线上,那还需要考虑几个额外的问题。
第一,CI机器上的Node.js、Java、hdc等工具需要提前安装好,或者使用Docker容器把环境打包起来。第二,CI机器通常是无界面的,跑测试时手机通过USB连接到机器上,需要保证设备权限对执行用户开放。第三,测试脚本里不要写死本机路径,尽量使用相对路径,这样换环境之后不用改脚本就能跑。
我见过不少测试工程,本地环境怎么配都正常,一上CI就跑挂,排查来排查去发现都是因为CI机器上少了某个环境变量或者驱动版本不对。建议你在配置CI环境时,先用一个最简脚本验证全链路,确认没有问题之后再接入完整测试套件。
7. 一些做事的心得体会
整套环境配置下来,我自己最大的感受是:鸿蒙设备的自动化环境搭建,难度其实不在于某一个单独步骤有多复杂,而在于工具链版本之间的搭配。很多人失败,就是因为用了老版本的Appium搭配新版本的鸿蒙系统,或者用了不兼容的Java版本,导致问题层出不穷。
我个人比较推荐的做法是,一次性把工具链全部更新到较新的稳定版本,宁可花点时间装新版,也尽量不要在排错上浪费更多时间。再就是,对于华为鸿蒙设备,hdc工具链一定要用对,它是连接的核心,不需要依赖adb,但理解adb的人可以很快上手hdc,两者在命令行使用习惯上非常接近。
最后再分享一个小技巧:配置过程中如果报错,不要只看报错信息最后一行,要把整个错误日志从头到尾扫一遍。很多时候关键信息都藏在中间部分,比如UIAutomator2驱动安装失败的具体原因、手机端某个服务崩溃的日志上下文。培养这个习惯,你能避免很多“照着网上的教程改了参数却依然失败”的尴尬情况。