鸿蒙UI测试框架:UITest
·
一、功能
UITest分为客户端和服务端:
| 端 | 说明 |
|---|---|
| 客户端 | 由测试应用加载,运行在应用进程。包含跨语言通信层、IPC模块,对外导出API |
| 服务端 | 以独立进程运行,通过IPC与客户端通信。负责核心逻辑:控件树构建、控件匹配查找、操作事件构造、多模事件注入等 |
UITest支持两种方式:
| 方式 | 说明 |
|---|---|
| ArkTS脚本开发 | 提供简洁易用的API接口,支持点击、双击、长按、滑动等操作 |
| 命令行测试 | 支持截图、获取控件树、录制界面操作、注入UI模拟事件 |
二、使用ArkTS接口进行UI测试
2.1 步骤
-
编写被测页面代码(如ClickToAfter.ets)
-
在ohosTest目录下编写测试代码
-
导入测试依赖:
@kit.TestKit、@ohos/hypium
2.2 核心流程
初始化Driver → 拉起被测应用 → 等待应用空闲 → 查找控件 → 执行操作 → 断言验证
2.3 示例
import { describe, expect, it, Level } from '@ohos/hypium';
import { abilityDelegatorRegistry, Driver, ON } from '@kit.TestKit';
import { UIAbility, Want } from '@kit.AbilityKit';
const delegator = abilityDelegatorRegistry.getAbilityDelegator();
export default function abilityTest() {
describe('ActsAbilityTest', () => {
it('testUiExample', Level.LEVEL3, async (done: Function) => {
const driver = Driver.create();
const bundleName = abilityDelegatorRegistry.getArguments().bundleName;
// 拉起被测应用
await delegator.startAbility({
bundleName: bundleName,
abilityName: 'EntryAbility'
});
// 等待应用拉起完成
await driver.waitForIdle(4000, 5000);
// 确认当前应用顶部Ability
const ability = await delegator.getCurrentTopAbility();
expect(ability.context.abilityInfo.name).assertEqual('EntryAbility');
// 查找"Next"控件并点击
const next = await driver.findComponent(ON.text('Next'));
await next.click();
await driver.waitForIdle(4000, 5000);
// 断言验证
await driver.assertComponentExist(ON.text('after click'));
await driver.pressBack();
done();
});
});
}
三、控件查找与操作
3.1 控件匹配器(ON)
UITest支持依据多种属性构造匹配器进行控件查找:
| 匹配方式 | 示例 |
|---|---|
| 按文本 | ON.text('Next') |
| 按类型 | ON.type('Button') |
| 相对位置 | ON.text('123').within(ON.type('Scroll')) |
| 按id | ON.id('button_id') |
3.2 示例
// 查找Button并点击
let button = await driver.findComponent(ON.type('Button'));
await button.click();
// 查找Scroll中文本为'123'的控件
let on = ON.text('123').within(ON.type('Scroll'));
let items = await driver.findComponents(on);
// 查找Image并进行双指放大
let image = await driver.findComponent(ON.type('Image'));
await image.pinchOut(1.5);
四、模拟触摸屏手指操作
4.1 基础操作
// 单击
await driver.click(100, 100);
// 指定屏幕id单击(API 20+)
await driver.clickAt({ x: 100, y: 100, displayId: 0 });
// 滑动
await driver.swipe(100, 100, 200, 200, 600);
// 指定屏幕id滑动(API 20+)
await driver.swipeBetween(
{ x: 100, y: 100, displayId: 0 },
{ x: 1000, y: 1000, displayId: 0 },
800
);
// 抛滑
await driver.fling({ x: 100, y: 100 }, { x: 200, y: 200 }, 5, 600);
// 指定方向抛滑
await driver.fling(UiDirection.DOWN, 10000);
// 拖拽
await driver.drag(100, 100, 200, 200, 600);
4.2 多指操作
// 2根手指,每根手指基于2个坐标点滑动
let pointers = PointerMatrix.create(2, 2);
pointers.setPoint(0, 0, { x: 100, y: 100 });
pointers.setPoint(0, 1, { x: 200, y: 100 });
pointers.setPoint(1, 0, { x: 100, y: 200 });
pointers.setPoint(1, 1, { x: 200, y: 200 });
await driver.injectMultiPointerAction(pointers);
五、页面加载等待
// 等待指定控件出现(超时1000ms)
let button = await driver.waitForComponent(ON.text('StartAbility Success!'), 1000);
// 等待应用空闲
await driver.waitForIdle(4000, 5000);
六、模拟文本输入
// 基于控件的文本输入
let input = await driver.findComponent(ON.type('TextInput'));
await input.inputText('abc');
// 指定复制粘贴方式输入(API 20+)
await input.inputText('abc', { paste: true, addition: true });
// 基于坐标的文本输入
let center = await input.getBoundsCenter();
await driver.inputText(center, 'abc');
// 包含中文时自动使用复制粘贴方式
await driver.inputText(center, '你好', { paste: false, addition: true });
输入方式:
| 参数 | 说明 |
|---|---|
paste |
是否以复制粘贴方式输入(默认false) |
addition |
是否以追加方式输入(不清空原有内容,默认false) |
七、截图
// 截取指定区域并保存
let savePath = '/data/storage/el2/base/cache/1.png';
let res = await driver.screenCapture(savePath, {
left: 0, top: 0, right: 100, bottom: 100
});
// 截取指定屏幕id的全屏(API 20+)
let disPlay = display.getDefaultDisplaySync();
await driver.screenCap(savePath, disPlay.id);
注意:截图路径需为应用沙箱路径(el2/user级加密区)。
八、UI事件监听
// 监听Toast控件出现
let observer = driver.createUIEventObserver();
observer.once('toastShow', (uiElementInfo) => {
let bundleName = uiElementInfo.bundleName;
let text = uiElementInfo.text;
let type = uiElementInfo.type;
});
九、模拟键鼠/触摸板/手写笔操作
9.1 键盘操作
import { KeyCode } from '@kit.InputKit';
// 按键输入
await driver.triggerKey(KeyCode.KEYCODE_BACK);
// 组合键输入(Ctrl+S)
await driver.triggerCombineKeys(KeyCode.KEYCODE_CTRL_LEFT, KeyCode.KEYCODE_S);
9.2 鼠标操作
import { MouseButton } from '@kit.TestKit';
// 鼠标左键单击
await driver.mouseClick({ x: 100, y: 100 }, MouseButton.MOUSE_BUTTON_LEFT);
// 鼠标移动
await driver.mouseMoveTo({ x: 100, y: 100 });
// 鼠标拖拽
await driver.mouseDrag({ x: 100, y: 100 }, { x: 200, y: 200 }, 600);
// 鼠标滚轮滚动(Ctrl+滚轮)
await driver.mouseScroll({ x: 100, y: 100 }, true, 30, KeyCode.KEYCODE_CTRL_LEFT);
9.3 触摸板操作(PC/2in1)
// 三指上滑返回桌面
await driver.touchPadMultiFingerSwipe(3, UiDirection.UP);
// 三指下滑恢复窗口
await driver.touchPadMultiFingerSwipe(3, UiDirection.DOWN);
9.4 手写笔操作
// 手写笔单击
await driver.penClick({ x: 100, y: 100 });
// 手写笔双击
await driver.penDoubleClick({ x: 100, y: 100 });
// 手写笔长按(0.5s)
await driver.penLongClick({ x: 100, y: 100 }, 0.5);
// 手写笔滑动
await driver.penSwipe({ x: 100, y: 100 }, { x: 100, y: 500 }, 600, 0.5);
十、窗口查找与操作
// 查找活跃窗口
let window = await driver.findWindow({ active: true });
// 窗口最小化
await window.minimize();
十一、基于命令行进行UI测试
前提:根据hdc命令行工具指导完成环境准备,确保设备已连接。
命令列表
| 命令 | 说明 |
|---|---|
uitest screenCap |
截图 |
uitest dumpLayout |
获取控件树 |
uitest uiRecord record |
录制界面操作 |
uitest uiRecord read |
读取录制数据 |
uitest uiInput |
注入UI模拟操作 |
uitest --version |
获取版本信息 |
uitest start-daemon |
拉起UITest测试进程 |
常用命令示例
截图:
# 默认路径
hdc shell uitest screenCap
# 指定路径
hdc shell uitest screenCap -p /data/local/tmp/1.png
获取控件树:
hdc shell uitest dumpLayout -p /data/local/tmp/1.json
录制界面操作:
# 开始录制(Ctrl+C结束)
hdc shell uitest uiRecord record
# 读取录制数据
hdc shell uitest uiRecord read
# 仅记录坐标(不匹配控件)
hdc shell uitest uiRecord record -W false
注入模拟操作:
# 单击
hdc shell uitest uiInput click 100 100
# 快滑
hdc shell uitest uiInput fling 10 10 200 200 500
# 慢滑
hdc shell uitest uiInput swipe 10 10 200 200 500
# 指定方向滑动(0左/1右/2上/3下)
hdc shell uitest uiInput dircFling 0 500
# 输入文本
hdc shell uitest uiInput inputText 100 100 hello
# 按键事件
hdc shell uitest uiInput keyEvent Home
hdc shell uitest uiInput keyEvent Back
# 组合键(Ctrl+V)
hdc shell uitest uiInput keyEvent 2072 2038
更多推荐


所有评论(0)