HarmonyOS7 UI 自动化测试:UiTest 框架从 0 到 1
文章目录

前言
你有没有试过改了一行代码,结果三个页面炸了?我上个月就干过这事——改了个按钮颜色,把整个订单流程搞崩了。手动测了两天才把问题找全,人都麻了。
从那以后我就在想:要是有一套自动化测试能替我点点点,该多好。
折腾了一周 UiTest 框架,终于跑通了第一个 UI 自动化测试用例。今天把整个过程分享出来,帮你少踩坑。
HarmonyOS7 提供了官方的 UI 自动化测试框架 UiTest,专门用来对 ArkUI 页面做自动化验证。说实话,之前我一直觉得写测试是浪费时间,直到那次改一行炸三页的事故,才真正意识到——没有测试的代码,就像没有刹车的车,早晚出事。
为什么要写 UI 测试
先聊聊为什么需要 UI 测试,而不是只靠单元测试。
单元测试管的是逻辑,但用户看到的、操作的是 UI。按钮能不能点?页面跳转对不对?列表滑到底部会不会崩?这些问题单元测试覆盖不了。
我之前的项目有个搜索页,单元测试全过,结果真机上输入法一弹出来就把搜索按钮遮住了。这种问题,只有 UI 测试能发现。
UI 自动化测试能帮我们做到:
- 回归保障:改代码不怕旧功能炸
- 持续集成:每次提交自动跑测试
- 减少手动测试:把重复的点点点交给机器
UiTest 框架概览
UiTest 是 HarmonyOS7 官方的 UI 自动化测试框架,核心能力包括:
| 能力 | 说明 |
|---|

| 组件查找 | 通过 id、text、type 等属性定位 UI 组件 |
| 模拟操作 | 点击、长按、滑动、输入文本等 |
| 断言验证 | 检查组件属性、页面状态是否符合预期 |
| 测试报告 | 自动生成测试结果报告 |
它的 API 风格跟 Android 的 UiAutomator 有点像,但更简洁。如果你写过 Android UI 测试,上手会很快。
环境搭建
写 UI 测试之前,得先把环境搭好。步骤不复杂,但有几个坑要注意。
1. 在模块的 oh-package.json5 中添加依赖:
{
"devDependencies": {
"@ohos/hypium": "1.0.6"
}
}
2. 在测试目录下创建测试文件:
测试文件放在 entry/src/ohosTest/ets/ 目录下,别放错位置了。ohosTest 是专门放仪器测试的目录,跟 test 目录不一样。
3. 配置测试运行器:
在 module.json5 里确认有测试配置:
{
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/EntryAbility.ets"
}
]
}

划重点:测试文件必须在
ohosTest目录下,否则框架识别不了。
查找组件
UiTest 的核心思路就两步:找到组件,操作组件。 找组件是第一步,也是最关键的一步。
按 id 查找:
import { Driver, ON } from '@ohos.UiTest';
const driver = Driver.create();
const button = await driver.findComponent(ON.id('loginButton'));
这段代码通过组件的 id 来查找。ON.id() 是最精确的查找方式,前提是你给组件设了 id。
按文本查找:
const textComp = await driver.findComponent(ON.text('登录'));
当组件没有设 id 时,可以通过显示文本来查找。不过这种方式有个隐患——文本改了,测试就挂了。 所以还是建议给关键组件加 id。
按类型查找:
const listComp = await driver.findComponent(ON.type('List'));
按组件类型查找,适合需要操作某个类型的容器组件时使用。
敲黑板:查找组件返回的是
Promise,必须用await。忘了加await是新手最常见的坑。
模拟操作
找到组件后,就可以模拟用户操作了。
点击操作:
const loginBtn = await driver.findComponent(ON.id('loginButton'));
await loginBtn.click();
click() 模拟单击。如果你需要长按,用 longClick()。
滑动操作:
await driver.swipe(200, 500, 200, 100, 500);
// 参数:起点x, 起点y, 终点x, 终点y, 滑动速度(ms)
swipe() 是屏幕级别的滑动,适合滚动页面、下拉刷新等场景。
输入文本:
const inputComp = await driver.findComponent(ON.id('searchInput'));
await inputComp.inputText('HarmonyOS7');
往输入框里填文字。注意这个操作会先清空原有内容,再输入新内容。
组合操作示例——模拟登录流程:
async function testLogin() {
const driver = Driver.create();
// 输入用户名
const usernameInput = await driver.findComponent(ON.id('username'));
await usernameInput.inputText('testuser');
// 输入密码
const passwordInput = await driver.findComponent(ON.id('password'));
await passwordInput.inputText('123456');
// 点击登录按钮
const loginBtn = await driver.findComponent(ON.id('loginButton'));
await loginBtn.click();
// 等待页面响应
await driver.delayMs(1000);
}
这段代码模拟了完整的登录操作。delayMs() 用来等待页面跳转,时间根据实际情况调整。
断言验证
操作完了,得验证结果对不对。这才是测试的核心——光操作不验证,那叫演示,不叫测试。
验证组件是否可见:
import { assert } from '@ohos/hypium';
const homeTitle = await driver.findComponent(ON.text('首页'));
assert.assertTrue(homeTitle !== null, '登录后应跳转到首页');
这段代码检查登录后是否出现了"首页"文字。如果组件找不到,说明跳转没成功。
验证组件属性:
const statusText = await driver.findComponent(ON.id('orderStatus'));
const text = await statusText.getText();
assert.assertEqual(text, '已完成', '订单状态应为已完成');
先拿到组件,再读取它的文本内容,跟预期值对比。assertEqual 会在值不匹配时抛出异常,测试标记为失败。
验证组件数量:
const listItems = await driver.findComponents(ON.type('ListItem'));
assert.assertEqual(listItems.length, 10, '列表应显示10条数据');
注意 findComponents 带 s,返回所有匹配的组件数组。适合验证列表数据是否正确加载。
血泪教训:断言一定要写清楚错误信息,不然测试挂了你看半天不知道哪里出了问题。
测试报告
测试跑完会自动生成报告。在 DevEco Studio 里右键测试文件 → Run Tests,执行完就能看到结果。
报告里包含:
| 信息 | 说明 |
|---|---|
| 用例总数 | 总共跑了多少条测试 |
| 通过数 | 绿色的,没问题的 |
| 失败数 | 红色的,需要排查 |
| 执行时间 | 每条用例耗时 |
| 失败截图 | 断言失败时自动截图 |
建议把 UI 测试集成到 CI 流水线里,每次提交代码自动跑一遍。这样谁改坏了东西,第一时间就能发现。
写在最后
UiTest 框架上手不难,关键是把组件 id 规划好。我现在的习惯是:所有用户可交互的组件必须设 id,按钮用 btnXxx,输入框用 inputXxx,统一命名。这样写测试的时候查找组件就轻松了。
还有一点:别一上来就想覆盖所有场景。 先从核心流程开始——登录、支付、关键操作路径,把这些保住了,再慢慢扩展。测试覆盖率 20% 但都是关键路径,比覆盖率 80% 但全是边缘场景有用得多。
如果你还没写过 UI 自动化测试,今天就可以动手试试。先跑通一个用例,你就知道有多香了。
更多推荐

所有评论(0)