一、功能

UITest分为客户端服务端

说明
客户端 由测试应用加载,运行在应用进程。包含跨语言通信层、IPC模块,对外导出API
服务端 以独立进程运行,通过IPC与客户端通信。负责核心逻辑:控件树构建、控件匹配查找、操作事件构造、多模事件注入等

UITest支持两种方式:

方式 说明
ArkTS脚本开发 提供简洁易用的API接口,支持点击、双击、长按、滑动等操作
命令行测试 支持截图、获取控件树、录制界面操作、注入UI模拟事件

二、使用ArkTS接口进行UI测试

2.1 步骤

  1. 编写被测页面代码(如ClickToAfter.ets)

  2. 在ohosTest目录下编写测试代码

  3. 导入测试依赖:@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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐