• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 自动化测试框架使用指导
2
3<!--Kit: Test Kit-->
4<!--Subsystem: Test-->
5<!--Owner: @inter515-->
6<!--Designer: @inter515-->
7<!--Tester: @laonie666-->
8<!--Adviser: @Brilliantry_Rui-->
9
10## 概述
11
12自动化测试框架arkxtest,作为工具集的重要组成部分,支持JS/TS语言的单元测试框架(JsUnit)、UI测试框架(UiTest)及白盒性能测试框架(PerfTest)。<br>JsUnit提供单元测试用例执行能力,提供用例编写基础接口,生成对应报告,用于测试系统或应用接口。<br>UiTest通过简洁易用的API提供查找和操作界面控件能力,支持用户开发基于界面操作的自动化测试脚本。<br>PerfTest提供基于代码段的白盒性能测试能力,支持采集指定代码段执行期间或指定场景发生时的性能数据。<br>本指南介绍了测试框架的主要功能、实现原理、环境准备,以及测试脚本编写和执行方法。同时,以shell命令方式,对外提供了获取截屏、控件树、录制界面操作、便捷注入UI模拟操作等能力,助力开发者更灵活方便测试和验证。
13
14## 实现原理
15
16测试框架分为单元测试框架、UI测试框架和白盒性能测试框架。<br>单元测试框架是测试框架的基础底座,提供了最基本的用例识别、调度、执行及结果汇总的能力。<br>UI测试框架主要对外提供了UiTest API供开发人员在对应测试场景调用,而其脚本的运行基础仍是单元测试框架。<br>白盒性能测试框架提供PerfTest API供开发人员在基于代码段的性能测试场景中使用,测试脚本基于单元测试框架开发。
17
18### 单元测试框架
19
20  图1.单元测试框架主要功能
21
22  ![](figures/UnitTest.PNG)
23
24  图2.脚本基础流程运行图
25
26  ![](figures/TestFlow.PNG)
27
28### UI测试框架
29
303.UI测试框架主要功能
31
32  ![](figures/Uitest.PNG)
33
34### 白盒性能测试框架
35
36  图4.白盒性能测试框架主要功能
37
38  <img src="figures/perftest.PNG" alt="perftest" width="760">
39
40## 基于ArkTS编写和执行测试
41
42### 搭建环境
43
44DevEco Studio可参考其官网介绍进行[下载](https://developer.huawei.com/consumer/cn/download/),并进行相关的配置动作。
45
46### 新建和编写测试脚本
47
48#### 新建测试脚本
49
50<!--RP2-->
51在DevEco Studio中新建应用开发工程,其中ohos目录即为测试脚本所在的目录。
52
53在工程目录下打开待测试模块下的ets文件,将光标置于代码中任意位置,单击**右键 > Show Context Actions** **> Create Ohos Test**或快捷键**Alt+enter** **> Create Ohos Test**创建测试类,更多指导请参考DevEco Studio中[指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/harmonyos_jnit_jsunit-0000001092459608-V3?catalogVersion=V3#section13366184061415)54
55<!--RP2End-->
56
57#### 编写单元测试脚本
58
59本章节主要描述单元测试框架支持能力,以及能力的使用方法,具体请参考[单元测试框架功能特性](https://gitee.com/openharmony/testfwk_arkxtest/blob/master/README_zh.md#%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%A1%86%E6%9E%B6%E5%8A%9F%E8%83%BD%E7%89%B9%E6%80%A7)60
61在单元测试框架,测试脚本需要包含如下基本元素:
62
631. 依赖导包,以便使用依赖的测试接口。
64
652. 测试代码编写,主要编写测试代码的相关逻辑,如接口调用等。
66
673. 断言接口调用,设置测试代码中的检查点,如无检查点,则不可认为一个完整的测试脚本。
68
69如下示例代码实现的场景是:启动测试页面,检查设备当前显示的页面是否为预期页面。
70
71```ts
72import { describe, it, expect, Level } from '@ohos/hypium';
73import { abilityDelegatorRegistry } from '@kit.TestKit';
74import { UIAbility, Want } from '@kit.AbilityKit';
75
76const delegator = abilityDelegatorRegistry.getAbilityDelegator();
77function sleep(time: number) {
78  return new Promise<void>((resolve: Function) => setTimeout(resolve, time));
79}
80export default function abilityTest() {
81  describe('ActsAbilityTest', () =>{
82    it('testUiExample',Level.LEVEL3, async (done: Function) => {
83      console.info("uitest: TestUiExample begin");
84      await sleep(1000);
85      const bundleName = abilityDelegatorRegistry.getArguments().bundleName;
86      //start tested ability
87      const want: Want = {
88        bundleName: bundleName,
89        abilityName: 'EntryAbility'
90      }
91      await delegator.startAbility(want);
92      await sleep(1000);
93      //check top display ability
94      const ability: UIAbility = await delegator.getCurrentTopAbility();
95      console.info("get top ability");
96      expect(ability.context.abilityInfo.name).assertEqual('EntryAbility');
97      done();
98    })
99  })
100}
101```
102
103#### 编写UI测试脚本
104
105本章节主要介绍UI测试框架支持能力,以及对应能力API的使用方法。<br>UI测试基于单元测试,UI测试脚本在单元测试脚本上增加了对UiTest接口,<!--RP1-->具体请参考[API文档](../reference/apis-test-kit/js-apis-uitest.md)<!--RP1End-->。<br>如下的示例代码是在上面的单元测试脚本基础上增量编写,实现的场景是:在启动的应用页面上进行点击操作,然后检测当前页面变化是否为预期变化。
106
1071. 编写Index.ets页面代码,作为被测示例demo。
108    ```ts
109    @Entry
110    @Component
111    struct Index {
112      @State message: string = 'Hello World';
113
114      build() {
115        Row() {
116          Column() {
117            Text(this.message)
118              .fontSize(50)
119              .fontWeight(FontWeight.Bold)
120            Text("Next")
121              .fontSize(50)
122              .margin({top:20})
123              .fontWeight(FontWeight.Bold)
124            Text("after click")
125              .fontSize(50)
126              .margin({top:20})
127              .fontWeight(FontWeight.Bold)
128          }
129          .width('100%')
130        }
131        .height('100%')
132      }
133    }
134    ```
135
1362. 在ohosTest > ets > test文件夹下.test.ets文件中编写具体测试代码。
137    ```ts
138    import { describe, it, expect, Level } from '@ohos/hypium';
139    // 导入测试依赖kit
140    import { abilityDelegatorRegistry, Driver, ON } from '@kit.TestKit';
141    import { UIAbility, Want } from '@kit.AbilityKit';
142
143    const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator();
144    function sleep(time: number) {
145      return new Promise<void>((resolve: Function) => setTimeout(resolve, time));
146    }
147    export default function abilityTest() {
148      describe('ActsAbilityTest', () => {
149        it('testUiExample',Level.LEVEL3, async (done: Function) => {
150            console.info("uitest: TestUiExample begin");
151            await sleep(1000);
152            const bundleName = abilityDelegatorRegistry.getArguments().bundleName;
153            //start tested ability
154            const want: Want = {
155              bundleName: bundleName,
156              abilityName: 'EntryAbility'
157            }
158            await delegator.startAbility(want);
159            await sleep(1000);
160            //check top display ability
161            const ability: UIAbility = await delegator.getCurrentTopAbility();
162            console.info("get top ability");
163            expect(ability.context.abilityInfo.name).assertEqual('EntryAbility');
164            //ui test code
165            //init driver
166            const driver = Driver.create();
167            await driver.delayMs(1000);
168            //find button on text 'Next'
169            const button = await driver.findComponent(ON.text('Next'));
170            //click button
171            await button.click();
172            await driver.delayMs(1000);
173            //check text
174            await driver.assertComponentExist(ON.text('after click'));
175            await driver.pressBack();
176            done();
177        })
178      })
179    }
180    ```
181
182#### 编写白盒性能测试脚本
183
184本章节主要介绍白盒性能测试框架支持能力,以及对应能力API的使用方法。<br>白盒性能测试基于单元测试,测试脚本在单元测试脚本上增加了对PerfTest接口的调用。<!--RP5-->具体请参考[API文档](../reference/apis-test-kit/js-apis-perftest.md)<!--RP5End-->。性能测试过程中,可以结合使用UI测试框架接口,对界面进行模拟操作并测试指定场景的性能。<br>如下示例代码实现的场景是:测试函数执行期间的应用性能、测试当前应用内列表滑动帧率。
185
1861.测试函数执行期间的应用性能。
187
188- 在main > ets > utils文件夹下新增PerfUtils.ets文件,在文件中编写自定义的函数。
189
190  ```ts
191  export class PerfUtils {
192    public static CalculateTest() {
193      let num: number = 0
194      for (let index = 0; index < 10000; index++) {
195        num++;
196      }
197    }
198  }
199  ```
200
201- 在ohosTest > ets > test文件夹下.test.ets文件中编写具体测试代码。
202
203  ```ts
204  import { describe, it, expect, Level } from '@ohos/hypium';
205  import { PerfMetric, PerfTest, PerfTestStrategy, PerfMeasureResult } from '@kit.TestKit';
206  import { PerfUtils } from '../../../main/ets/utils/PerfUtils';
207
208  export default function PerfTestTest() {
209    describe('PerfTestTest', () => {
210      it('testExample0', Level.LEVEL3, async (done: Function) => {
211        let metrics: Array<PerfMetric> = [PerfMetric.DURATION, PerfMetric.CPU_USAGE] // 指定被测指标
212        let actionCode = async (finish: Callback<boolean>) => { // 测试代码段中使用uitest进行列表滑动
213          await PerfUtils.CalculateTest()
214          finish(true);
215        };
216        let perfTestStrategy: PerfTestStrategy = {  // 定义测试策略
217          metrics: metrics,
218          actionCode: actionCode,
219        };
220        try {
221          let perfTest: PerfTest = PerfTest.create(perfTestStrategy); // 创建测试任务对象PerfTest
222          await perfTest.run(); // 执行测试,异步函数需使用await同步等待完成
223          let res1: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.DURATION); // 获取耗时指标的测试结果
224          let res2: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.CPU_USAGE); // 获取CPU使用率指标的测试结果
225          perfTest.destroy(); // 销毁PerfTest对象
226          expect(res1.average).assertLessOrEqual(1000); // 断言性能测试结果
227          expect(res2.average).assertLessOrEqual(30); // 断言性能测试结果
228        } catch (error) {
229          console.error(`Failed to execute perftest. Cause:${JSON.stringify(error)}`);
230          expect(false).assertTrue()
231        }
232        done();
233      })
234    })
235  }
236  ```
237
2382.测试当前应用内列表滑动帧率
239
240- 编写Index.ets页面代码,作为被测示例demo。
241
242  ```ts
243  @Entry
244  @Component
245  struct ListPage {
246    scroller: Scroller = new Scroller()
247    private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
248    build() {
249      Row() {
250        Column() {
251          Scroll(this.scroller) {
252            Column() {
253              ForEach(this.arr, (item: number) => {
254                Text(item.toString())
255                  .width('90%')
256                  .height('40%')
257                  .fontSize(80)
258                  .textAlign(TextAlign.Center)
259                  .margin({ top: 10 })
260              }, (item: string) => item)
261            }
262          }
263          .width('100%')
264          .height('100%')
265          .scrollable(ScrollDirection.Vertical)
266          .scrollBar(BarState.On)
267          .scrollBarColor(Color.Gray)
268        }
269        .width('100%')
270      }
271      .height('100%')
272    }
273  }
274  ```
275
276- 在ohosTest > ets > test文件夹下.test.ets文件中编写具体测试代码。
277
278  ```ts
279  import { describe, it, expect, Level } from '@ohos/hypium';
280  import { PerfMetric, PerfTest, PerfTestStrategy, PerfMeasureResult } from '@kit.TestKit';
281  import { abilityDelegatorRegistry, Driver, ON } from '@kit.TestKit';
282  import { Want } from '@kit.AbilityKit';
283
284  const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator();
285  export default function PerfTestTest() {
286    describe('PerfTestTest', () => {
287      it('testExample',Level.LEVEL3, async (done: Function) => {
288        let driver = Driver.create();
289        await driver.delayMs(1000);
290        const bundleName = abilityDelegatorRegistry.getArguments().bundleName;
291        const want: Want = {
292          bundleName: bundleName,
293          abilityName: 'EntryAbility'
294        };
295        await delegator.startAbility(want); // 打开测试页面
296        await driver.delayMs(1000);
297        let scroll = await driver.findComponent(ON.type('Scroll'));
298        await driver.delayMs(1000);
299        let center = await scroll.getBoundsCenter();  // 获取Scroll可滚动组件坐标
300        await driver.delayMs(1000);
301        let metrics: Array<PerfMetric> = [PerfMetric.LIST_SWIPE_FPS]  // 指定被测指标为列表滑动帧率
302        let actionCode = async (finish: Callback<boolean>) => { // 测试代码段中使用uitest进行列表滑动
303          await driver.fling({x: center.x, y: Math.floor(center.y * 3 / 2)}, {x: center.x, y: Math.floor(center.y / 2)}, 50, 20000);
304          await driver.delayMs(3000);
305          finish(true);
306        };
307        let resetCode = async (finish: Callback<boolean>) => {  // 复位环境,将列表划至顶部
308          await scroll.scrollToTop(40000);
309          await driver.delayMs(1000);
310          finish(true);
311        };
312        let perfTestStrategy: PerfTestStrategy = {  // 定义测试策略
313          metrics: metrics,
314          actionCode: actionCode,
315          resetCode: resetCode,
316          iterations: 5,  // 指定测试迭代次数
317          timeout: 50000, // 指定actionCode和resetCode的超时时间
318        };
319        try {
320          let perfTest: PerfTest = PerfTest.create(perfTestStrategy); // 创建测试任务对象PerfTest
321          await perfTest.run(); // 执行测试,异步函数需使用await同步等待完成
322          let res: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.LIST_SWIPE_FPS); // 获取列表滑动帧率指标的测试结果
323          perfTest.destroy(); // 销毁PerfTest对象
324          expect(res.average).assertLargerOrEqual(60);  // 断言性能测试结果
325        } catch (error) {
326          console.error(`Failed to execute perftest. Cause:${JSON.stringify(error)}`);
327        }
328        done();
329      })
330    })
331  }
332  ```
333
334### 执行测试脚本
335
336#### 在DevEco Studio执行
337
338脚本执行需要连接硬件设备。通过点击按钮执行,当前支持以下执行方式:
339
3401. 测试包级别执行,即执行测试包内的全部用例。
341
3422. 测试套级别执行,即执行describe方法中定义的全部测试用例。
343
3443. 测试方法级别执行,即执行指定it方法也就是单条测试用例。
345
346![](figures/Execute.PNG)
347
348**查看测试结果**
349
350测试执行完毕后可直接在DevEco Studio中查看测试结果,如下图示例所示。
351
352![](figures/TestResult.PNG)
353
354**查看测试用例覆盖率**
355
356执行完测试用例后可以查看测试用例覆盖率,具体操作请参考[代码测试](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-code-test)下各章节内的覆盖率统计模式。
357
358#### 在CMD执行
359
360脚本执行需要连接硬件设备,将应用测试包安装到测试设备上,在cmd窗口中执行aa命令,完成对用例测试。
361
362> **说明:**
363>
364> 使用cmd的方式,需要配置好hdc相关的环境变量。
365
366**aa test命令执行配置参数**
367
368| 执行参数全写  | 执行参数缩写 | 执行参数含义                           | 执行参数示例                       |
369| ------------- | ------------ | -------------------------------------- | ---------------------------------- |
370| --bundleName  | -b           | 应用Bundle名称。                       | - b com.test.example               |
371| --packageName | -p           | 应用模块名,适用于FA模型应用。           | - p com.test.example.entry         |
372| --moduleName  | -m           | 应用模块名,适用于STAGE模型应用。        | -m entry                           |
373| NA            | -s           | 特定参数,以<key, value>键值对方式传入。 | - s unittest /ets/testrunner/OpenHarmonyTestRunner |
374
375框架当前支持多种用例执行方式,通过上表中的-s参数后的配置键值对参数传入触发,如下表所示。
376
377| 配置参数名     | 配置参数含义                                                 | 配置参数取值                                               | 配置参数示例                              |
378| ------------ | -----------------------------------------------------------------------------    | ------------------------------------------------------------ | ----------------------------------------- |
379| unittest     | 用例执行所使用OpenHarmonyTestRunner对象。  | OpenHarmonyTestRunner或用户自定义runner名称                  | - s unittest OpenHarmonyTestRunner        |
380| class        | 指定要执行的测试套或测试用例。                                  | {describeName}#{itName},{describeName}                      | -s class attributeTest#testAttributeIt    |
381| notClass     | 指定不需要执行的测试套或测试用例。                               | {describeName}#{itName},{describeName}                      | -s notClass attributeTest#testAttributeIt |
382| itName       | 指定要执行的测试用例。                                         | {itName}                                                     | -s itName testAttributeIt                 |
383| timeout      | 测试用例执行的超时时间。                                        | 正整数(单位ms),如不设置默认为 5000                        | -s timeout 15000                          |
384| breakOnError | 遇错即停模式,当执行用例断言失败或者发生错误时,退出测试执行流程。 | true,false(默认值)                                          | -s breakOnError true                      |
385| random | 测试用例随机顺序执行。                  | true,false(默认值)                                           | -s random true                      |
386| testType     | 指定要执行用例的用例类型。                     | function,performance,power,reliability,security,global,compatibility,user,standard,safety,resilience | -s testType function                      |
387| level        | 指定要执行用例的用例级别。                     | 0, 1, 2, 3, 4                                              | -s level 0                                |
388| size         | 指定要执行用例的用例规模。                     | small,medium,large                                        | -s size small
389| stress       | 指定要执行用例的执行次数。                     |  正整数                                         | -s stress 1000                            |
390
391**在cmd窗口执行test命令**
392
393> **说明:**
394>
395>参数配置和命令均是基于Stage模型。
396
397
398示例代码1:执行所有测试用例。
399
400```shell
401 hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner
402```
403
404示例代码2:执行指定的describe测试套用例,指定多个需用逗号隔开。
405
406```shell
407  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s class s1,s2
408```
409
410示例代码3:执行指定测试套中指定的用例,指定多个需用逗号隔开。
411
412```shell
413  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s class testStop#stop_1,testStop1#stop_0
414```
415
416示例代码4:执行指定除配置以外的所有的用例,设置不执行多个测试套需用逗号隔开。
417
418```shell
419  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s notClass testStop
420```
421
422示例代码5:执行指定it名称的所有用例,指定多个需用逗号隔开。
423
424```shell
425  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s itName stop_0
426```
427
428示例代码6:用例执行超时时长配置。
429
430```shell
431  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s timeout 15000
432```
433
434示例代码7:用例以breakOnError模式执行用例。
435
436```shell
437  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s breakOnError true
438```
439
440示例代码8:执行测试类型匹配的测试用例。
441
442```shell
443  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s testType function
444```
445
446示例代码9:执行测试级别匹配的测试用例。
447
448```shell
449  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s level 0
450```
451
452示例代码10:执行测试规模匹配的测试用例。
453
454```shell
455  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s size small
456```
457
458示例代码11:执行测试用例指定次数。
459
460```shell
461  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s stress 1000
462```
463
464**查看测试结果**
465
466- cmd模式执行过程,会打印如下相关日志信息。
467
468 ```
469  OHOS_REPORT_STATUS: class=testStop
470  OHOS_REPORT_STATUS: current=1
471  OHOS_REPORT_STATUS: id=JS
472  OHOS_REPORT_STATUS: numtests=447
473  OHOS_REPORT_STATUS: stream=
474  OHOS_REPORT_STATUS: test=stop_0
475  OHOS_REPORT_STATUS_CODE: 1
476
477  OHOS_REPORT_STATUS: class=testStop
478  OHOS_REPORT_STATUS: current=1
479  OHOS_REPORT_STATUS: id=JS
480  OHOS_REPORT_STATUS: numtests=447
481  OHOS_REPORT_STATUS: stream=
482  OHOS_REPORT_STATUS: test=stop_0
483  OHOS_REPORT_STATUS_CODE: 0
484  OHOS_REPORT_STATUS: consuming=4
485 ```
486
487| 日志输出字段               | 日志输出字段含义       |
488| -------           | -------------------------|
489| OHOS_REPORT_SUM    | 当前测试套用例总数。 |
490| OHOS_REPORT_STATUS: class | 当前执行用例测试套名称。|
491| OHOS_REPORT_STATUS: id | 用例执行语言,默认JS。  |
492| OHOS_REPORT_STATUS: numtests | 测试包中测试用例总数 。|
493| OHOS_REPORT_STATUS: stream | 当前用例发生错误时,记录错误信息。 |
494| OHOS_REPORT_STATUS: test| 当前用例执行的it name。 |
495| OHOS_REPORT_STATUS_CODE | 当前用例执行结果状态。0表示通过,1表示错误,2表示失败。|
496| OHOS_REPORT_STATUS: consuming | 当前用例执行消耗的时长(ms)。 |
497
498- cmd执行完成后,会打印如下相关日志信息。
499
500 ```
501  OHOS_REPORT_RESULT: stream=Tests run: 447, Failure: 0, Error: 1, Pass: 201, Ignore: 245
502  OHOS_REPORT_CODE: 0
503
504  OHOS_REPORT_RESULT: breakOnError model, Stopping whole test suite if one specific test case failed or error
505  OHOS_REPORT_STATUS: taskconsuming=16029
506
507 ```
508
509| 日志输出字段               | 日志输出字段含义           |
510| ------------------| -------------------------|
511| run    | 当前测试包用例总数。 |
512| Failure | 当前测试失败用例个数。 |
513| Error | 当前执行用例发生错误用例个数。  |
514| Pass | 当前执行用例通过用例个数。|
515| Ignore | 当前未执行用例个数。 |
516| taskconsuming| 执行当前测试用例总耗时(ms)。 |
517
518> **说明:**
519>
520> 当处于breakOnError模式,用例发生错误时,注意查看Ignore以及中断说明。
521
522## 基于shell命令测试
523
524在开发过程中,若需要快速进行截屏、录制界面操作、注入UI模拟操作、获取控件树等操作,可以使用shell命令,更方便完成相应测试。
525
526> **说明:**
527>
528> 使用cmd的方式,需要配置好hdc相关的环境变量。
529
530**命令列表**
531| 命令            | 配置参数   |描述                              |
532|---------------|---------------------------------|---------------------------------|
533| help          | help|  显示uitest工具能够支持的命令信息。            |
534| screenCap       |[-p] | 截屏。非必填。<br>指定存储路径和文件名,只支持存放在/data/local/tmp/下。<br>默认存储路径:/data/local/tmp,文件名:时间戳 + .png。 |
535| dumpLayout      |[-p] \<-i \| -a>|支持在daemon运行时执行获取控件树。<br> **-p** :指定存储路径和文件名,只支持存放在/data/local/tmp/下。默认存储路径:/data/local/tmp,文件名:时间戳 + .json。<br> **-i** :不过滤不可见控件,也不做窗口合并。<br> **-a** :保存 BackgroundColor、 Content、FontColor、FontSize、extraAttrs 属性数据。<br> **默认** :不保存上述属性数据。<br> **-a和-i** 不可同时使用。 |
536| uiRecord        | uiRecord \<record \| read>|录制界面操作。  <br> **record** :开始录制,将当前界面操作记录到/data/local/tmp/record.csv,结束录制操作使用Ctrl+C结束录制。  <br> **read** :读取并且打印录制数据。<br>各参数代表的含义请参考[用户录制操作](#用户录制操作)。|
537| uiInput       | \<help \| click \| doubleClick \| longClick \| fling \| swipe \| drag \| dircFling \| inputText \| keyEvent>| 注入UI模拟操作。<br>各参数代表的含义请参考[注入ui模拟操作](#注入ui模拟操作)。                       |
538| --version | --version|获取当前工具版本信息。                     |
539| start-daemon|start-daemon| 拉起uitest测试进程。 |
540
541### 截图使用示例
542
543```bash
544# 存储路径:/data/local/tmp,文件名:时间戳 + .png。
545hdc shell uitest screenCap
546# 指定存储路径和文件名,存放在/data/local/tmp/下。
547hdc shell uitest screenCap -p /data/local/tmp/1.png
548```
549
550### 获取控件树使用示例
551
552```bash
553hdc shell uitest dumpLayout -p /data/local/tmp/1.json
554```
555
556### 用户录制操作
557>**说明**
558>
559> 录制过程中,需等待当前操作的识别结果在命令行输出后,再进行下一步操作。
560
561**命令列表**
562| 命令   | 配置参数    |  必填 | 描述              |
563|-------|--------------|------|-----------------|
564| -W    | \<true/false> | 否   | 录制过程中是否保存操作坐标对应的控件信息到/data/local/tmp/record.csv文件中。true表示保存控件信息,false表示仅记录坐标信息,不设置时默认为true。 |
565| -l    |              | 否   | 在每次操作后保存当前布局信息,文件保存路径:/data/local/tmp/layout_录制启动时间戳_操作序号.json。 |
566| -c    | \<true/false> | 否   | 是否将录制到的操作事件信息打印到控制台,true表示打印,false表示打印,不设置时默认为true。 |
567
568```bash
569# 将当前界面操作记录到/data/local/tmp/record.csv,结束录制操作使用Ctrl+C结束录制。
570hdc shell uitest uiRecord record
571# 录制时仅记录操作对应的坐标,不匹配目标控件。
572hdc shell uitest uiRecord record -W false
573# 每次操作后,保存页面布局,文件保存路径:/data/local/tmp/layout_录制启动时间戳_操作序号.json。
574hdc shell uitest uiRecord record -l
575# 录制到的操作事件信息不打印到控制台。
576hdc shell uitest uiRecord record -c false
577# 读取并打印录制数据。
578hdc shell uitest uiRecord read
579```
580
581以下举例为:record数据中包含的字段及字段含义,仅供参考。
582
583 ```
584 {
585	 "ABILITY": "com.ohos.launcher.MainAbility", // 前台应用界面
586	 "BUNDLE": "com.ohos.launcher", // 操作应用
587	 "CENTER_X": "", // 预留字段,暂未使用
588	 "CENTER_Y": "", // 预留字段,暂未使用
589	 "EVENT_TYPE": "pointer", //
590	 "LENGTH": "0", // 总体步长
591	 "OP_TYPE": "click", //事件类型,当前支持点击、双击、长按、拖拽、滑动、抛滑动作录制
592	 "VELO": "0.000000", // 离手速度
593	 "direction.X": "0.000000",// 总体移动X方向
594	 "direction.Y": "0.000000", // 总体移动Y方向
595	 "duration": 33885000.0, // 手势操作持续时间
596	 "fingerList": [{
597		 "LENGTH": "0", // 总体步长
598		 "MAX_VEL": "40000", // 最大速度
599		 "VELO": "0.000000", // 离手速度
600		 "W1_BOUNDS": "{"bottom":361,"left":37,"right":118,"top":280}", // 起点控件bounds
601		 "W1_HIER": "ROOT,3,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0", // 起点控件hierarchy
602		 "W1_ID": "", // 起点控件id
603		 "W1_Text": "", // 起点控件text
604		 "W1_Type": "Image", // 起点控件类型
605		 "W2_BOUNDS": "{"bottom":361,"left":37,"right":118,"top":280}", // 终点控件bounds
606		 "W2_HIER": "ROOT,3,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0", // 终点控件hierarchy
607		 "W2_ID": "", // 终点控件id
608		 "W2_Text": "", // 终点控件text
609		 "W2_Type": "Image", // 终点控件类型
610		 "X2_POSI": "47", // 终点X
611		 "X_POSI": "47", // 起点X
612		 "Y2_POSI": "301", // 终点Y
613		 "Y_POSI": "301", // 起点Y
614		 "direction.X": "0.000000", // x方向移动量
615		 "direction.Y": "0.000000" // Y方向移动量
616	 }],
617	 "fingerNumber": "1" //手指数量
618 }
619 ```
620
621### 注入UI模拟操作
622
623| 命令   | 必填 | 描述              |
624|------|------|-----------------|
625| help   | 是    | uiInput命令相关帮助信息。 |
626| click   | 是    | 模拟单击操作。具体请参考下方**uiInput click/doubleClick/longClick使用示例**。      |
627| doubleClick   | 是    | 模拟双击操作。具体请参考下方**uiInput click/doubleClick/longClick使用示例**。      |
628| longClick   | 是    | 模拟长按操作。具体请参考下方**uiInput click/doubleClick/longClick使用示例**。     |
629| fling   | 是    | 模拟快滑操作。具体请参考下方**uiInput fling使用示例使用示例**。   |
630| swipe   | 是    | 模拟慢滑操作。具体请参考下方**uiInput swipe/drag使用示例**。     |
631| drag   | 是    | 模拟拖拽操作。具体请参考下方**uiInput swipe/drag使用示例**。     |
632| dircFling   | 是    | 模拟指定方向滑动操作。具体请参考下方**uiInput dircFling使用示例**。     |
633| inputText   | 是    | 指定坐标点,模拟输入框输入文本操作。具体请参考下方**uiInput inputText使用示例**。                   |
634| text   | 是    | 无需指定坐标点,在当前获焦处,模拟输入框输入文本操作。具体请参考下方**uiInput text使用示例**。                           |
635| keyEvent   | 是    | 模拟实体按键事件(如:键盘,电源键,返回上一级,返回桌面等),以及组合按键操作。具体请参考下方**uiInput keyEvent使用示例**。     |
636
637
638#### uiInput click/doubleClick/longClick使用示例
639
640| 配置参数    | 必填 | 描述            |
641|---------|------|-----------------|
642| point_x | 是      | 点击x坐标点。 |
643| point_y | 是       | 点击y坐标点。 |
644
645```shell
646# 执行单击事件。
647hdc shell uitest uiInput click 100 100
648
649# 执行双击事件。
650hdc shell uitest uiInput doubleClick 100 100
651
652# 执行长按事件。
653hdc shell uitest uiInput longClick 100 100
654```
655
656#### uiInput fling使用示例
657
658| 配置参数  | 必填             | 描述               |
659|------|------------------|-----------------|
660| from_x   | 是                | 滑动起点x坐标。 |
661| from_y   | 是                | 滑动起点y坐标。 |
662| to_x   | 是                | 滑动终点x坐标。 |
663| to_y   | 是                | 滑动终点y坐标。 |
664| swipeVelocityPps_   | 否      | 滑动速度,单位:px/s,取值范围:200-40000。<br> 默认值:600。 |
665| stepLength_   | 否 | 滑动步长。默认值:滑动距离/50。<br>  **为实现更好的模拟效果,推荐参数缺省/使用默认值。**  |
666
667
668```shell
669# 执行快滑操作,stepLength_缺省。
670hdc shell uitest uiInput fling 10 10 200 200 500
671```
672
673#### uiInput swipe/drag使用示例
674
675| 配置参数  | 必填             | 描述               |
676|------|------------------|-----------------|
677| from_x   | 是                | 滑动起点x坐标。 |
678| from_y   | 是                | 滑动起点y坐标。 |
679| to_x   | 是                | 滑动终点x坐标。 |
680| to_y   | 是                | 滑动终点y坐标。 |
681| swipeVelocityPps_   | 否      | 滑动速度,单位:px/s,取值范围:200-40000。<br> 默认值:600。 |
682
683```shell
684# 执行慢滑操作。
685hdc shell uitest uiInput swipe 10 10 200 200 500
686
687# 执行拖拽操作。
688hdc shell uitest uiInput drag 10 10 100 100 500
689```
690
691#### uiInput dircFling使用示例
692
693| 配置参数             | 必填       | 描述 |
694|-------------------|-------------|----------|
695| direction         | 否 | 滑动方向,取值范围:[0,1,2,3],默认值为0。<br> 0代表向左滑动,1代表向右滑动,2代表向上滑动,3代表向下滑动。    |
696| swipeVelocityPps_ | 否| 滑动速度,单位:px/s,取值范围:200-40000。<br> 默认值: 600。    |
697| stepLength        | 否        | 滑动步长。<br> 默认值: 滑动距离/50。为更好的模拟效果,推荐参数缺省/使用默认值。 |
698
699```shell
700# 执行左滑操作。
701hdc shell uitest uiInput dircFling 0 500
702# 执行向右滑动操作。
703hdc shell uitest uiInput dircFling 1 600
704# 执行向上滑动操作。
705hdc shell uitest uiInput dircFling 2
706# 执行向下滑动操作。
707hdc shell uitest uiInput dircFling 3
708```
709
710#### uiInput inputText使用示例
711
712| 配置参数             | 必填       | 描述 |
713|------|------------------|----------|
714| point_x   | 是                | 输入框x坐标点。 |
715| point_y   | 是                | 输入框y坐标点。 |
716| text   | 是                | 输入文本内容。  |
717
718```shell
719# 执行输入框输入操作。
720hdc shell uitest uiInput inputText 100 100 hello
721```
722
723#### uiInput text使用示例
724
725| 配置参数             | 必填       | 描述 |
726|------|------------------|----------|
727| text   | 是                | 输入文本内容。  |
728
729```shell
730# 无需输入坐标点,在当前获焦处,执行输入框输入操作。若当前获焦处不支持文本输入,则无实际效果。
731hdc shell uitest uiInput text hello
732```
733
734#### uiInput keyEvent使用示例
735
736| 配置参数             | 必填       | 描述                                                                                                                              |
737|------|------|---------------------------------------------------------------------------------------------------------------------------------|
738| keyID1   | 是    | 实体按键对应ID,取值范围:Back、Home、Power、或[KeyCode键码值](../reference/apis-input-kit/js-apis-keycode.md#keycode)。<br>当取值为Back、Home或Power时,不支持输入组合键。 <br>当前注入大写锁定键(KeyCode=2074)无效,请使用组合键实现大写字母输入。如“按键shift+按键V”输入大写字母V。 |
739| keyID2    | 否    | 实体按键对应ID,取值范围:[KeyCode键码值](../reference/apis-input-kit/js-apis-keycode.md#keycode),默认值为空。                                               |
740| keyID3    | 否    | 实体按键对应ID,取值范围:[KeyCode键码值](../reference/apis-input-kit/js-apis-keycode.md#keycode),默认值为空。                                               |
741
742```shell
743# 返回主页。
744hdc shell uitest uiInput keyEvent Home
745# 返回。
746hdc shell uitest uiInput keyEvent Back
747# 组合键粘贴。
748hdc shell uitest uiInput keyEvent 2072 2038
749# 输入小写字母v。
750hdc shell uitest uiInput keyEvent 2038
751# 输入大写字母V。
752hdc shell uitest uiInput keyEvent 2047 2038
753```
754
755### 获取版本信息
756
757```bash
758hdc shell uitest --version
759```
760### 拉起uitest测试进程
761
762```shell
763hdc shell uitest start-daemon
764```
765
766>**说明**
767>
768> 设备需调成开发者模式。
769>
770> 仅元能力aa test拉起的测试hap才能调用Uitest的能力。
771>
772> 测试hap的<!--RP4-->[APL等级级别](../security/AccessToken/app-permission-mgmt-overview.md#权限机制中的基本概念)<!--RP4End-->需为system_basic、normal。
773
774<!--Del-->
775## 相关实例
776
777### 单元测试脚本实例
778
779#### 单元测试断言功能使用实例
780介绍单元测试框架中支持的断言能力如何使用,具体代码请查看[断言能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/jsunit/entry/src/ohosTest/ets/test/assertExampleTest/assertExample.test.ets)781
782#### 单元测试测试套定义使用实例
783介绍单元测试框架测试套嵌套如何定义,包括嵌套定义能力,具体代码请参考[测试套嵌套示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/jsunit/entry/src/ohosTest/ets/test/coverExampleTest/coverExample.test.ets)784
785#### 单元测试测试应用自定义函数使用实例
786介绍针对应用内自定义函数如何使用框架能力进行测试,具体代码请参考[应用自定义函数测试示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/jsunit/entry/src/ohosTest/ets/test/customExampleTest/customExample.test.ets)787
788#### 单元测试数据驱动能力使用实例
789介绍测试框架数据驱动能力、脚本重复执行配置功能,具体代码请参考[数据驱动能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/jsunit/entry/src/ohosTest/ets/test/paramExampleTest/paramExample.test.ets)790
791### UI测试脚本实例(控件类)
792
793#### 查找指定控件能力实例
794介绍通过设置控件属性作为查找条件,在应用界面上查找组件对象,具体代码请参考[控件查找示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/findCommentExampleTest/Component/findCommentExample.test.ets)795
796#### 模拟点击操作事件能力实例
797介绍模拟用户在应用界面上进行点击,长按,双击等事件,具体代码请参考[点击事件示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/clickEvent.test.ets)798
799#### 模拟鼠标操作能力实例
800介绍模拟鼠标左击、右击、滑轮事件,具体代码请参考[鼠标操作事件示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/MouseEvent.test.ets)801
802#### 模拟文本输入能力实例
803介绍模拟输入中文、英文文本内容,仅支持可输入文本的组件进行操作,例如文本框等,具体代码请参考[文本输入能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/InputEvent.test.ets)804
805#### 截图能力实例
806介绍屏幕截图功能,包括指定区域截图能力,具体代码请参考[截图能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/ScreenCapEvent.test.ets)807
808#### 模拟快滑操作能力实例
809介绍模拟快滑操作能力,即在可滑动页面上进行滑动,滑动后手指离开屏幕,具体代码请参考[模拟快滑操作能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/FlingEvent.test.ets)810
811#### 模拟慢滑操作能力实例
812介绍模拟慢滑操作能力,即在可滑动页面上进行滑动,滑动后手指仍停留在屏幕,具体代码请参考[模拟慢滑操作能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/SwipeEvent.test.ets)813
814#### 模拟缩放操作能力实例
815介绍模拟缩放能力,即在支持放大缩小的图片上,模拟双指缩放操作的能力,具体代码请参考[模拟缩放操作能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/PinchEvent.test.ets)816
817#### 模拟滚动到组件顶端或底端能力实例
818介绍模拟针对滑动类组件,可以模拟操作直接滚动到组件顶端或底端,具体代码请参考[模拟滚动到组件顶端或底端示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/ui/ScrollerEvent.test.ets)819
820### UI测试脚本实例(窗口类)
821
822#### 查找指定窗口能力实例
823介绍通过应用包名查找应用窗口,具体代码请参考[查找指定窗口能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/findCommentExampleTest/window/findWindowExample.test.ets)824
825#### 模拟窗口移动能力实例
826介绍模拟移动窗口到指定位置能力,具体代码请参考[模拟窗口移动示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/window/MoveToEvent.test.ets)827
828#### 模拟调整窗口大小能力实例
829介绍模拟调整窗口大小能力,并可指定调整的具体方向,具体代码请参考[模拟调整窗口大小能力示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/uitest/entry/src/ohosTest/ets/test/operationExampleTest/window/ReSizeWindow.test.ets)830
831### 白盒性能测试脚本实例
832
833介绍调用PerfTest接口,实现白盒性能测试的能力,具体代码请参考[白盒性能测试示例](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/Project/Test/perftest/entry/src/ohosTest/ets/test/PerfTest.test.ets)834
835<!--DelEnd-->
836
837## 常见问题
838
839### 单元测试用例常见问题
840
841**1. 用例中增加的打印日志在用例结果之后才打印**
842
843**问题描述**
844
845用例中增加的日志打印信息,没有在用例执行过程中出现,而是在用例执行结束之后才出现。
846
847**可能原因**
848
849此类情况只会存在于用例中有调用异步接口的情况,原则上用例中所有的日志信息均在用例执行结束之前打印。
850
851**解决方法**
852
853当被调用的异步接口多于一个时,建议将接口调用封装成Promise方式调用。
854
855**2. 执行用例时报error:fail to start ability**
856
857**问题描述**
858
859执行测试用例时候,用例执行失败,控制台返回错误:fail to start ability。
860
861**可能原因**
862
863测试包打包过程中出现问题,未将测试框架依赖文件打包在测试包中。
864
865**解决方法**
866
867检查测试包中是否包含OpenHarmonyTestRunner.abc文件,如没有则重新编译打包后再次执行测试。
868
869**3. 执行用例时报用例超时错误**
870
871**问题描述**
872
873用例执行结束,控制台提示execute time XXms错误,即用例执行超时。
874
875**可能原因**
876
8771. 用例执行异步接口,但执行过程中没有执行到done函数,导致用例执行一直没有结束,直到超时结束。
878
8792. 用例调用函数耗时过长,超过用例执行设置的超时时间。
880
8813. 用例调用函数中断言失败,抛出失败异常,导致用例执行一直没有结束,直到超时结束。
882
883**解决方法**
884
8851. 检查用例代码逻辑,确保即使断言失败场景认可走到done函数,保证用例执行结束。
886
8872. 可在DevEco Studio中Run/Debug Configurations中修改用例执行超时配置参数,避免用例执行超时。
888
8893. 检查用例代码逻辑,断言结果,确保断言Pass。
890### UI测试用例常见问题
891
892**1. 失败日志有“Get windows failed/GetRootByWindow failed”错误信息**
893
894**问题描述**
895
896UI测试用例执行失败,查看hilog日志发现日志中有“Get windows failed/GetRootByWindow failed”错误信息。
897
898**可能原因**
899
900系统ArkUI开关未开启,导致被测试界面控件树信息未生成。
901
902**解决方法**
903
904执行如下命令,并重启设备再次执行用例。
905
906```shell
907hdc shell param set persist.ace.testmode.enabled 1
908```
909
910**2. 失败日志有“uitest-api does not allow calling concurrently”错误信息**
911
912**问题描述**
913
914UI测试用例执行失败,查看hilog日志发现日志中有“uitest-api does not allow calling concurrently”错误信息。
915
916**可能原因**
917
9181. 用例中UI测试框架提供异步接口没有增加await语法糖调用。
919
9202. 多进程执行UI测试用例,导致拉起多个UITest进程,框架不支持多进程调用。
921
922**解决方法**
923
9241. 检查用例实现,异步接口增加await语法糖调用。
925
9262. 避免多进程执行UI测试用例。
927
928**3. 失败日志有“does not exist on current UI! Check if the UI has changed after you got the widget object”错误信息**
929
930**问题描述**
931
932UI测试用例执行失败,查看hilog日志发现日志中有“does not exist on current UI! Check if the UI has changed after you got the widget object”错误信息。
933
934**可能原因**
935
936在用例中代码查找到目标控件后,设备界面发生了变化,导致查找到的控件丢失,无法进行下一步的模拟操作。
937
938**解决方法**
939
940重新执行UI测试用例。