• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 自动化测试框架使用介绍
2
3## 简介
4 OpenHarmony自动化测试框架代码部件仓arkxtest,包含单元测试框架(JsUnit)、Ui测试框架(UiTest)和白盒性能测试框架(PerfTest)。
5
6 单元测试框架(JsUnit)提供单元测试用例执行能力,提供用例编写基础接口,生成对应报告,用于测试系统或应用接口。
7
8 Ui测试框架(UiTest)通过简洁易用的API提供查找和操作界面控件能力,支持用户开发基于界面操作的自动化测试脚本。
9
10 PerfTest提供基于代码段的白盒性能测试能力,支持采集指定代码段执行期间或指定场景发生时的性能数据。
11
12## 目录
13
14```
15arkxtest
16  |-----jsunit  单元测试框架
17  |-----UiTest  Ui测试框架
18  |-----perftest  白盒性能测试框架
19```
20## 约束限制
21本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
22
23## 单元测试框架功能特性
24
25| No.  | 特性     | 功能说明                                               |
26| ---- | -------- |----------------------------------------------------|
27| 1    | 基础流程 | 支持编写及异步执行基础用例。                                     |
28| 2    | 断言库   | 判断用例实际结果值与预期值是否相符。                                 |
29| 3    | Mock能力 | 支持函数级mock能力,对定义的函数进行mock后修改函数的行为,使其返回指定的值或者执行某种动作。 |
30| 4    | 数据驱动 | 提供数据驱动能力,支持复用同一个测试脚本,使用不同输入数据驱动执行。                 |
31| 5    | 专项能力 | 支持测试套与用例筛选、随机执行、压力测试、超时设置、遇错即停模式,跳过,支持测试套嵌套等。      |
32
33### 使用说明
34
35####  基础流程
36
37测试用例采用业内通用语法,describe代表一个测试套, it代表一条用例。
38
39| No. | API               | 功能说明                                                                   |
40|-----| ----------------- |------------------------------------------------------------------------|
41| 1   | describe          | 定义一个测试套,支持两个参数:测试套名称和测试套函数。其中测试套函数不能是异步函数。                             |
42| 2   | beforeAll         | 在测试套内定义一个预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数。                        |
43| 3   | beforeEach        | 在测试套内定义一个单元预置条件,在每条测试用例开始前执行,执行次数与it定义的测试用例数一致,支持一个参数:预置动作函数。          |
44| 4   | afterEach         | 在测试套内定义一个单元清理条件,在每条测试用例结束后执行,执行次数与it定义的测试用例数一致,支持一个参数:清理动作函数。          |
45| 5   | afterAll          | 在测试套内定义一个清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数。                        |
46| 6   | beforeItSpecified | @since1.0.15在测试套内定义一个单元预置条件,仅在指定测试用例开始前执行,支持两个参数:单个用例名称或用例名称数组、预置动作函数。 |
47| 7   | afterItSpecified  | @since1.0.15在测试套内定义一个单元清理条件,仅在指定测试用例结束后执行,支持两个参数:单个用例名称或用例名称数组、清理动作函数。 |
48| 8   | it                | 定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数。                                        |
49| 9   | expect            | 支持bool类型判断等多种断言方法。                                                     |
50| 10  | xdescribe    | @since1.0.17定义一个跳过的测试套,支持两个参数:测试套名称和测试套函数。                             |
51| 11  | xit                | @since1.0.17定义一条跳过的测试用例,支持三个参数:用例名称,过滤参数和用例函数。                         |
52
53
54beforeItSpecified, afterItSpecified 示例代码:
55
56```javascript
57import { describe, it, expect, beforeItSpecified, afterItSpecified } from '@ohos/hypium';
58export default function beforeItSpecifiedTest() {
59  describe('beforeItSpecifiedTest', () => {
60    beforeItSpecified(['String_assertContain_success'], () => {
61      const num:number = 1;
62      expect(num).assertEqual(1);
63    })
64    afterItSpecified(['String_assertContain_success'], async (done: Function) => {
65      const str:string = 'abc';
66      setTimeout(()=>{
67        try {
68          expect(str).assertContain('b');
69        } catch (error) {
70          console.error(`error message ${JSON.stringify(error)}`);
71        }
72        done();
73      }, 1000)
74    })
75    it('String_assertContain_success', 0, () => {
76      let a: string = 'abc';
77      let b: string = 'b';
78      expect(a).assertContain(b);
79      expect(a).assertEqual(a);
80    })
81  })
82}
83```
84
85####  断言库
86
87##### 断言功能列表
88
89
90| No. | API                | 功能说明                                                        |
91|:----| :------------------|-------------------------------------------------------------|
92| 1   | assertClose        | 检验actualvalue和expectvalue(0)的接近程度是否是expectValue(1)。         |
93| 2   | assertContain      | 检验actualvalue中是否包含expectvalue。                              |
94| 3   | assertEqual        | 检验actualvalue是否等于expectvalue[0]。                            |
95| 4   | assertFail         | 抛出一个错误。                                                     |
96| 5   | assertFalse        | 检验actualvalue是否是false。                                      |
97| 6   | assertTrue         | 检验actualvalue是否是true。                                       |
98| 7   | assertInstanceOf   | 检验actualvalue是否是expectvalue类型,支持基础类型。                       |
99| 8   | assertLarger       | 检验actualvalue是否大于expectvalue。                               |
100| 9   | assertLargerOrEqual       | 检验actualvalue是否大于等于expectvalue。                             |
101| 10  | assertLess         | 检验actualvalue是否小于expectvalue。                               |
102| 11  | assertLessOrEqual         | 检验actualvalue是否小于等于expectvalue。                             |
103| 12  | assertNull         | 检验actualvalue是否是null。                                       |
104| 13  | assertThrowError   | 检验actualvalue抛出Error内容是否是expectValue。                       |
105| 14  | assertUndefined    | 检验actualvalue是否是undefined。                                  |
106| 15  | assertNaN          | @since1.0.4 检验actualvalue是否是一个NaN。                          |
107| 16  | assertNegUnlimited | @since1.0.4 检验actualvalue是否等于Number.NEGATIVE_INFINITY。      |
108| 17  | assertPosUnlimited | @since1.0.4 检验actualvalue是否等于Number.POSITIVE_INFINITY。      |
109| 18  | assertDeepEquals   | @since1.0.4 检验actualvalue和expectvalue是否完全相等。                |
110| 19  | assertPromiseIsPending | @since1.0.4 判断promise是否处于Pending状态。                         |
111| 20  | assertPromiseIsRejected | @since1.0.4 判断promise是否处于Rejected状态。                        |
112| 21  | assertPromiseIsRejectedWith | @since1.0.4 判断promise是否处于Rejected状态,并且比较执行的结果值。             |
113| 22  | assertPromiseIsRejectedWithError | @since1.0.4 判断promise是否处于Rejected状态并有异常,同时比较异常的类型和message值。 |
114| 23  | assertPromiseIsResolved | @since1.0.4 判断promise是否处于Resolved状态。                        |
115| 24  | assertPromiseIsResolvedWith | @since1.0.4 判断promise是否处于Resolved状态,并且比较执行的结果值。             |
116| 25  | not                | @since1.0.4 断言取反,支持上面所有的断言功能。                               |
117| 26  | message                | @since1.0.17自定义断言异常信息。                                      |
118
119expect断言示例代码:
120
121```javascript
122import { describe, it, expect } from '@ohos/hypium';
123
124export default function expectTest() {
125  describe('expectTest', () => {
126    it('assertCloseTest', 0, () => {
127      let a: number = 100;
128      let b: number = 0.1;
129      expect(a).assertClose(99, b);
130    })
131    it('assertContain_1', 0, () => {
132      let a = "abc";
133      expect(a).assertContain('b');
134    })
135    it('assertContain_2', 0, () => {
136      let a = [1, 2, 3];
137      expect(a).assertContain(1);
138    })
139    it('assertEqualTest', 0, () => {
140      expect(3).assertEqual(3);
141    })
142    it('assertFailTest', 0, () => {
143      expect().assertFail() // 用例失败;
144    })
145    it('assertFalseTest', 0, () => {
146      expect(false).assertFalse();
147    })
148    it('assertTrueTest', 0, () => {
149      expect(true).assertTrue();
150    })
151    it('assertInstanceOfTest', 0, () => {
152      let a: string = 'strTest';
153      expect(a).assertInstanceOf('String');
154    })
155    it('assertLargerTest', 0, () => {
156      expect(3).assertLarger(2);
157    })
158    it('assertLessTest', 0, () => {
159      expect(2).assertLess(3);
160    })
161    it('assertNullTest', 0, () => {
162      expect(null).assertNull();
163    })
164    it('assertThrowErrorTest', 0, () => {
165      expect(() => {
166        throw new Error('test')
167      }).assertThrowError('test');
168    })
169    it('assertUndefinedTest', 0, () => {
170      expect(undefined).assertUndefined();
171    })
172    it('assertLargerOrEqualTest', 0, () => {
173      expect(3).assertLargerOrEqual(3);
174    })
175    it('assertLessOrEqualTest', 0, () => {
176      expect(3).assertLessOrEqual(3);
177    })
178    it('assertNaNTest', 0, () => {
179      expect(Number.NaN).assertNaN(); // true
180    })
181    it('assertNegUnlimitedTest', 0, () => {
182      expect(Number.NEGATIVE_INFINITY).assertNegUnlimited(); // true
183    })
184    it('assertPosUnlimitedTest', 0, () => {
185      expect(Number.POSITIVE_INFINITY).assertPosUnlimited(); // true
186    })
187    it('deepEquals_null_true', 0, () => {
188      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
189      expect(null).assertDeepEquals(null);
190    })
191    it('deepEquals_array_not_have_true', 0, () => {
192      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
193      const a: Array<number> = [];
194      const b: Array<number> = [];
195      expect(a).assertDeepEquals(b);
196    })
197    it('deepEquals_map_equal_length_success', 0, () => {
198      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
199      const a: Map<number, number> = new Map();
200      const b: Map<number, number> = new Map();
201      a.set(1, 100);
202      a.set(2, 200);
203      b.set(1, 100);
204      b.set(2, 200);
205      expect(a).assertDeepEquals(b);
206    })
207    it("deepEquals_obj_success_1", 0, () => {
208      const a: SampleTest = {x: 1};
209      const b: SampleTest = {x: 1};
210      expect(a).assertDeepEquals(b);
211    })
212    it("deepEquals_regExp_success_0", 0, () => {
213      const a: RegExp = new RegExp("/test/");
214      const b: RegExp = new RegExp("/test/");
215      expect(a).assertDeepEquals(b);
216    })
217    it('assertPromiseIsPendingTest', 0, async () => {
218      let p: Promise<void> = new Promise<void>(() => {});
219      await expect(p).assertPromiseIsPending();
220    })
221    it('assertPromiseIsRejectedTest', 0, async () => {
222      let info: PromiseInfo = {res: "no"};
223      let p: Promise<PromiseInfo> = Promise.reject(info);
224      await expect(p).assertPromiseIsRejected();
225    })
226    it('assertPromiseIsRejectedWithTest', 0, async () => {
227      let info: PromiseInfo = {res: "reject value"};
228      let p: Promise<PromiseInfo> = Promise.reject(info);
229      await expect(p).assertPromiseIsRejectedWith(info);
230    })
231    it('assertPromiseIsRejectedWithErrorTest', 0, async () => {
232      let p1: Promise<TypeError> = Promise.reject(new TypeError('number'));
233      await expect(p1).assertPromiseIsRejectedWithError(TypeError);
234    })
235    it('assertPromiseIsResolvedTest', 0, async () => {
236      let info: PromiseInfo = {res: "result value"};
237      let p: Promise<PromiseInfo> = Promise.resolve(info);
238      await expect(p).assertPromiseIsResolved();
239    })
240    it('assertPromiseIsResolvedWithTest', 0, async () => {
241      let info: PromiseInfo = {res: "result value"};
242      let p: Promise<PromiseInfo> = Promise.resolve(info);
243      await expect(p).assertPromiseIsResolvedWith(info);
244    })
245    it("test_message", 0, () => {
246      expect(1).message('1 is not equal 2!').assertEqual(2); // fail
247    })
248  })
249}
250
251interface SampleTest {
252  x: number;
253}
254
255interface PromiseInfo {
256  res: string;
257}
258```
259
260##### 自定义断言@since1.0.18
261
262示例代码:
263
264```javascript
265import { describe, Assert, beforeAll, expect, Hypium, it } from '@ohos/hypium';
266
267// custom.ets
268interface customAssert extends Assert {
269  // 自定义断言声明
270  myAssertEqual(expectValue: boolean): void;
271}
272
273//自定义断言实现
274let myAssertEqual = (actualValue: boolean, expectValue: boolean) => {
275  interface R {
276  pass: boolean,
277  message: string
278}
279
280let result: R = {
281  pass: true,
282  message: 'just is a msg'
283}
284
285let compare = () => {
286  if (expectValue === actualValue) {
287    result.pass = true;
288    result.message = '';
289  } else {
290    result.pass = false;
291    result.message = 'expectValue !== actualValue!';
292  }
293  return result;
294}
295result = compare();
296return result;
297}
298
299export default function customAssertTest() {
300  describe('customAssertTest', () => {
301    beforeAll(() => {
302      //注册自定义断言,只有先注册才可以使用
303      Hypium.registerAssert(myAssertEqual);
304    })
305    it('assertContain1', 0, () => {
306      let a = true;
307      let b = true;
308      (expect(a) as customAssert).myAssertEqual(b);
309      Hypium.unregisterAssert(myAssertEqual);
310    })
311    it('assertContain2', 0, () => {
312      Hypium.registerAssert(myAssertEqual);
313      let a = true;
314      let b = true;
315      (expect(a) as customAssert).myAssertEqual(b);
316      // 注销自定义断言,注销以后就无法使用
317      Hypium.unregisterAssert(myAssertEqual);
318      try {
319        (expect(a) as customAssert).myAssertEqual(b);
320      }catch(e) {
321        expect(e.message).assertEqual("myAssertEqual is unregistered");
322      }
323    })
324  })
325}
326```
327
328#### 异步代码测试
329
330 **异步测试错误示例代码:**
331```javascript
332import { describe, it, expect } from '@ohos/hypium';
333
334async function callBack(fn: Function) {
335   setTimeout(fn, 5000, 'done')
336}
337
338export default function callBackErrorTest() {
339  describe('callBackErrorTest', () => {
340    it('callBackErrorTest', 0, () => {
341      callBack((result: string) => {
342        try {
343          // 用例失败
344          expect().assertFail();
345        } catch (e) {
346        } finally {
347        }
348      })
349    })
350  })
351}
352```
353> - 上述测试用例中,测试函数结束后, 回调函数才执行, 导致用例结果错误。
354> - 当使用框架测试异步代码时,框架需要知道它测试的代码何时完成。以确保测试用例结果正常统计,测试框架用以下两种方式来处理这个问题。
355
356##### Async/Await
357> 使用 Async关键字定义一个异步测试函数,在测试函数中使用await等待测试函数完成。
358
359**Promise示例代码:**
360
361```javascript
362import { describe, it, expect } from '@ohos/hypium';
363
364async function method_1() {
365  return new Promise<string>((res: Function, rej: Function) => {
366    //做一些异步操作
367    setTimeout(() => {
368      console.log('执行');
369      res('method_1_call');
370    }, 5000);
371  });
372}
373
374export default function abilityTest() {
375  describe('ActsAbilityTest', () => {
376    it('assertContain', 0, async () => {
377      let result = await method_1();
378      expect(result).assertEqual('method_1_call');
379    })
380  })
381}
382```
383##### done 函数
384>  - done函数是测试函数的一个可选回调参数,在测试用例中手动调用,测试框架将等待done回调被调用,然后才完成测试。
385>  - 当测试函数中定义done函数参数时,测试用例中必须手动调用done函数,否则用例失败会出现超时错误。
386
387
388**Promise回调示例代码:**
389```javascript
390import { describe, it, expect } from '@ohos/hypium';
391async function method_1() {
392  return new Promise<string>((res: Function, rej: Function) => {
393    //做一些异步操作
394    setTimeout(() => {
395      console.log('执行');
396      res('method_1_call');
397    }, 5000);
398  });
399}
400
401export default function abilityTest() {
402  describe('Promise_Done', () => {
403    it('Promise_Done', 0,(done: Function) => {
404      method_1().then((result: string) => {
405        try {
406          expect(result).assertEqual('method_1_call');
407        } catch (e) {
408        } finally {
409          // 调用done函数,用例执行完成,必须手动调用done函数,否则出现超时错误。
410          done()
411        }
412      })
413
414    })
415  })
416}
417```
418
419**回调函数示例代码:**
420```javascript
421import { describe, it, expect } from '@ohos/hypium';
422
423async function callBack(fn: Function) {
424   setTimeout(fn, 5000, 'done')
425}
426
427export default function callBackTestTest() {
428  describe('CallBackTest', () => {
429    it('CallBackTest_001', 0, (done: Function) => {
430      callBack( (result: string) => {
431        try {
432          expect(result).assertEqual('done');
433        } catch (e) {
434        } finally {
435          // 调用done函数,用例执行完成,必须手动调用done函数,否则出现超时错误。
436          done()
437        }
438      })
439    })
440  })
441}
442```
443
444#### SysTestKit的公共能力
445
446| No. | API                | 功能说明              |
447|:----| :------------------|-------------------|
448| 1   | getDescribeName        | 获取当前测试用例所属的测试套名称。 |
449| 2   | getItName        | 获取当初测试用例名称。       |
450| 3   | getItAttribute        | 获取当初测试用例等级。       |
451| 4   | actionStart        | 添加用例执行过程打印自定义日志。  |
452| 5   | actionEnd        | 添加用例执行过程打印自定义日志。  |
453| 6   | existKeyword        | 检测hilog日志中是否打印。   |
454
455##### 获取当前测试用例所属的测试套名称
456
457示例代码:
458```javascript
459import { describe, it, expect, SysTestKit } from '@ohos/hypium';
460import hilog from '@ohos.hilog';
461const domain = 0;
462const tag = 'SysTestKitTest'
463export default function abilityTest() {
464  describe('SysTestKitTest', () => {
465
466    it("testGetDescribeName", 0, () => {
467      hilog.debug(domain, tag, `testGetDescribeName start`);
468      const describeName = SysTestKit.getDescribeName();
469      hilog.debug(domain, tag, `testGetDescribeName describeName, ${describeName}`);
470      expect(describeName).assertEqual('SysTestKitTest');
471      hilog.debug(domain, tag, `testGetDescribeName end`);
472    })
473  })
474}
475```
476
477##### 获取当初测试用例名称
478
479示例代码:
480```javascript
481import { describe, it, expect, SysTestKit } from '@ohos/hypium';
482import hilog from '@ohos.hilog';
483const domain = 0;
484const tag = 'SysTestKitTest'
485export default function abilityTest() {
486  describe('SysTestKitTest', () => {
487
488    it("testGetItName", 0, () => {
489      hilog.debug(domain, tag, `testGetDescribeName start`);
490      const itName = SysTestKit.getItName();
491      hilog.debug(domain, tag, `testGetDescribeName itName, ${itName}`);
492      expect(itName).assertEqual('testGetItName');
493      hilog.debug(domain, tag, `testGetDescribeName end`);
494    })
495  })
496}
497```
498
499##### 获取当初测试用例级别
500
501示例代码:
502```javascript
503import { describe, it, expect, SysTestKit, TestType, Level, Size } from '@ohos/hypium';
504import hilog from '@ohos.hilog';
505const domain = 0;
506const tag = 'SysTestKitTest'
507export default function abilityTest() {
508  describe('SysTestKitTest', () => {
509
510    it("testGetItAttribute", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, () => {
511      hilog.debug(domain, tag, `testGetItAttribute start`);
512      const testType: TestType | Size | Level = SysTestKit.getItAttribute();
513      hilog.debug(domain, tag, `testGetDescribeName testType, ${ testType }`);
514      expect(testType).assertEqual(TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0);
515      hilog.debug(domain, tag, `testGetItAttribute end`);
516    })
517  })
518}
519```
520
521##### 添加自定义打印日志。
522
523示例代码:
524```javascript
525import { describe, it, expect, SysTestKit, TestType, Level, Size } from '@ohos/hypium';
526import hilog from '@ohos.hilog';
527const domain = 0;
528const tag = 'SysTestKitTest'
529export default function abilityTest() {
530  describe('SysTestKitTest', () => {
531
532    it("testActionStart", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, () => {
533      hilog.debug(domain, tag, `testActionStart start `);
534      SysTestKit.actionStart('testActionStart 自定义日志 ');
535      SysTestKit.actionEnd('testActionStart end 自定义日志 ');
536      hilog.debug(domain, tag, `testActionStart end`);
537    })
538  })
539}
540```
541
542##### 检测hilog日志中是否打印。
543
544示例代码:
545```javascript
546import { describe, it, expect, SysTestKit, TestType, Level, Size } from '@ohos/hypium';
547import hilog from '@ohos.hilog';
548const domain = 0;
549const tag = 'SysTestKitTest'
550
551function logTest() {
552  hilog.debug(domain, 'test', `logTest called selfTest`);
553}
554
555export default function abilityTest() {
556  describe('SysTestKitTest', () => {
557
558    it("testExistKeyword", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, async () => {
559      hilog.debug(domain, tag, `testExistKeyword start `);
560      logTest();
561      const isCalled = await SysTestKit.existKeyword('logTest');
562      hilog.debug(domain, tag, `testExistKeyword isCalled, ${isCalled} `);
563      expect(isCalled).assertTrue();
564      hilog.debug(domain, tag, `testExistKeyword end`);
565    })
566  })
567}
568```
569
570#### Mock能力
571
572##### 约束限制
573
574单元测试框架Mock能力从npm包[1.0.1版本](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fhypium)开始支持,需修改源码工程中package.info中配置依赖npm包版本号后使用。
575> -  仅支持mock自定义对象,不支持mock系统API对象。
576> -  不支持mock对象的私有函数。
577-  **接口列表:**
578
579| No. | API | 功能说明                                                                                                                                            |
580| --- | --- |-------------------------------------------------------------------------------------------------------------------------------------------------|
581| 1 | mockFunc(obj: object, f:function) | mock某个类的对象obj的函数f,那么需要传两个参数:obj和f,支持使用异步函数(说明:对mock而言原函数实现是同步或异步没太多区别,因为mock并不关注原函数的实现)。                                                        |
582| 2 | when(mockedfunc:function) | 对传入后方法做检查,检查是否被mock并标记过,返回的是一个方法声明。                                                                                                             |
583| 3 | afterReturn(x:value) | 设定预期返回一个自定义的值value,比如某个字符串或者一个promise。                                                                                                          |
584| 4 | afterReturnNothing() | 设定预期没有返回值,即 undefined。                                                                                                                          |
585| 5 | afterAction(x:action) | 设定预期返回一个函数执行的操作。                                                                                                                                |
586| 6 | afterThrow(x:msg) | 设定预期抛出异常,并指定异常msg。                                                                                                                              |
587| 7 | clear(obj: object) | 用例执行完毕后,进行数据mocker对象的还原处理(还原之后对象恢复被mock之前的功能)。                                                                                                  |
588| 8 | any | 设定用户传任何类型参数(undefined和null除外),执行的结果都是预期的值,使用ArgumentMatchers.any方式调用。                                                                           |
589| 9 | anyString | 设定用户传任何字符串参数,执行的结果都是预期的值,使用ArgumentMatchers.anyString方式调用。                                                                                      |
590| 10 | anyBoolean | 设定用户传任何boolean类型参数,执行的结果都是预期的值,使用ArgumentMatchers.anyBoolean方式调用。                                                                               |
591| 11 | anyFunction | 设定用户传任何function类型参数,执行的结果都是预期的值,使用ArgumentMatchers.anyFunction方式调用。                                                                             |
592| 12 | anyNumber | 设定用户传任何数字类型参数,执行的结果都是预期的值,使用ArgumentMatchers.anyNumber方式调用。                                                                                     |
593| 13 | anyObj | 设定用户传任何对象类型参数,执行的结果都是预期的值,使用ArgumentMatchers.anyObj方式调用。                                                                                        |
594| 14 | matchRegexs(Regex) | 设定用户传任何正则表达式类型参数Regex,执行的结果都是预期的值,使用ArgumentMatchers.matchRegexs(Regex)方式调用。                                                                    |
595| 15 | verify(methodName, argsArray) | 验证methodName(函数名字符串)所对应的函数和其参数列表argsArray的执行行为是否符合预期,返回一个VerificationMode:一个提供验证模式的类,它有times(count)、once()、atLeast(x)、atMost(x)、never()等函数可供选择。 |
596| 16 | times(count) | 验证行为调用过count次。                                                                                                                                  |
597| 17 | once() | 验证行为调用过一次。                                                                                                                                      |
598| 18 | atLeast(count) | 验证行为至少调用过count次。                                                                                                                                |
599| 19 | atMost(count) | 验证行为至多调用过count次。                                                                                                                                |
600| 20 | never | 验证行为从未发生过。                                                                                                                                      |
601| 21 | ignoreMock(obj, method) | 使用ignoreMock可以还原obj对象中被mock后的函数,对被mock后的函数有效。                                                                                                   |
602| 22 | clearAll() | 用例执行完毕后,进行数据和内存清理,不会还原obj对象中被mock后的函数。                                                                                                                  |                                                                                                                            |
603
604-  **使用示例:**
605
606用户可以通过以下方式引入mock模块进行测试用例编写:
607
608- **须知:**
609使用时候必须引入的mock能力模块: MockKit,when,根据自己用例需要引入断言能力api。
610例如:`import { describe, expect, it, MockKit, when} from '@ohos/hypium'`
611
612**示例1: afterReturn 的使用**
613
614```javascript
615import { describe, expect, it, MockKit, when } from '@ohos/hypium';
616
617class ClassName {
618  constructor() {
619  }
620
621  method_1(arg: string) {
622    return '888888';
623  }
624
625  method_2(arg: string) {
626    return '999999';
627  }
628}
629export default function afterReturnTest() {
630  describe('afterReturnTest', () => {
631    it('afterReturnTest', 0, () => {
632      console.info("it1 begin");
633      // 1.创建一个mock能力的对象MockKit
634      let mocker: MockKit = new MockKit();
635      // 2.定类ClassName,里面两个函数,然后创建一个对象claser
636      let claser: ClassName = new ClassName();
637      // 3.进行mock操作,比如需要对ClassName类的method_1函数进行mock
638      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
639      // 4.期望claser.method_1函数被mock后, 以'test'为入参时调用函数返回结果'1'
640      when(mockfunc)('test').afterReturn('1');
641      // 5.对mock后的函数进行断言,看是否符合预期
642      // 执行成功案例,参数为'test'
643      expect(claser.method_1('test')).assertEqual('1'); // 执行通过
644    })
645  })
646}
647```
648- **须知:**
649`when(mockfunc)('test').afterReturn('1');`
650这句代码中的`('test')`是mock后的函数需要传递的匹配参数,目前支持传递多个参数。
651`afterReturn('1')`是用户需要预期返回的结果。
652有且只有在参数是`('test')`的时候,执行的结果才是用户自定义的预期结果。
653
654**示例2: afterReturnNothing 的使用**
655
656```javascript
657import { describe, expect, it, MockKit, when } from '@ohos/hypium';
658
659class ClassName {
660  constructor() {
661  }
662
663  method_1(arg: string) {
664    return '888888';
665  }
666
667  method_2(arg: string) {
668    return '999999';
669  }
670}
671export default function  afterReturnNothingTest() {
672  describe('afterReturnNothingTest', () => {
673    it('testMockfunc', 0, () => {
674      console.info("it1 begin");
675      // 1.创建一个mock能力的对象MockKit
676      let mocker: MockKit = new MockKit();
677      // 2.定类ClassName,里面两个函数,然后创建一个对象claser
678      let claser: ClassName = new ClassName();
679      // 3.进行mock操作,比如需要对ClassName类的method_1函数进行mock
680      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
681      // 4.期望claser.method_1函数被mock后, 以'test'为入参时调用函数返回结果undefined
682      when(mockfunc)('test').afterReturnNothing();
683      // 5.对mock后的函数进行断言,看是否符合预期,注意选择跟第4步中对应的断言方法
684      // 执行成功案例,参数为'test',这时候执行原对象claser.method_1的方法,会发生变化
685      // 这时候执行的claser.method_1不会再返回'888888',而是设定的afterReturnNothing()生效// 不返回任何值;
686      expect(claser.method_1('test')).assertUndefined(); // 执行通过
687    })
688  })
689}
690```
691
692**示例3: 设定参数类型为any ,即接受任何参数(undefined和null除外)的使用**
693
694
695- **须知:**
696需要引入ArgumentMatchers类,即参数匹配器,例如:ArgumentMatchers.any
697
698```javascript
699import { describe, expect, it, MockKit, when, ArgumentMatchers } from '@ohos/hypium';
700
701class ClassName {
702  constructor() {
703  }
704
705  method_1(arg: string) {
706    return '888888';
707  }
708
709  method_2(arg: string) {
710    return '999999';
711  }
712}
713export default function argumentMatchersAnyTest() {
714  describe('argumentMatchersAnyTest', () => {
715    it('testMockfunc', 0, () => {
716      console.info("it1 begin");
717      // 1.创建一个mock能力的对象MockKit
718      let mocker: MockKit = new MockKit();
719      // 2.定类ClassName,里面两个函数,然后创建一个对象claser
720      let claser: ClassName = new ClassName();
721      // 3.进行mock操作,比如需要对ClassName类的method_1函数进行mock
722      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
723      // 4.期望claser.method_1函数被mock后, 以任何参数调用函数时返回结果'1'
724      when(mockfunc)(ArgumentMatchers.any).afterReturn('1');
725      // 5.对mock后的函数进行断言,看是否符合预期,注意选择跟第4步中对应的断言方法
726      // 执行成功的案例1,传参为字符串类型
727      expect(claser.method_1('test')).assertEqual('1'); // 用例执行通过。
728      // 执行成功的案例2,传参为数字类型123
729      expect(claser.method_1("123")).assertEqual('1');// 用例执行通过。
730      // 执行成功的案例3,传参为boolean类型true
731      expect(claser.method_1("true")).assertEqual('1');// 用例执行通过。
732    })
733  })
734}
735```
736
737**示例4: 设定参数类型ArgumentMatchers的使用**
738
739```javascript
740import { describe, expect, it, MockKit, when, ArgumentMatchers } from '@ohos/hypium';
741
742class ClassName {
743  constructor() {
744  }
745
746  method_1(arg: string) {
747    return '888888';
748  }
749
750  method_2(arg: string) {
751    return '999999';
752  }
753}
754export default function argumentMatchersTest() {
755  describe('argumentMatchersTest', () => {
756    it('testMockfunc', 0, () => {
757      console.info("it1 begin");
758      // 1.创建一个mock能力的对象MockKit
759      let mocker: MockKit = new MockKit();
760      // 2.定类ClassName,里面两个函数,然后创建一个对象claser
761      let claser: ClassName = new ClassName();
762      // 3.进行mock操作,比如需要对ClassName类的method_1函数进行mock
763      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
764      // 4.期望claser.method_1函数被mock后, 以任何string类型为参数调用函数时返回结果'1'
765      when(mockfunc)(ArgumentMatchers.anyString).afterReturn('1');
766      // 4.对mock后的函数进行断言,看是否符合预期,注意选择跟第4步中对应的断言方法
767      // 执行成功的案例,传参为字符串类型
768      expect(claser.method_1('test')).assertEqual('1'); // 用例执行通过。
769      expect(claser.method_1('abc')).assertEqual('1'); // 用例执行通过。
770    })
771  })
772}
773```
774
775**示例5: 设定参数类型为matchRegexs(Regex)等 的使用**
776```javascript
777import { describe, expect, it, MockKit, when, ArgumentMatchers } from '@ohos/hypium';
778
779class ClassName {
780  constructor() {
781  }
782
783  method_1(arg: string) {
784    return '888888';
785  }
786
787  method_2(arg: string) {
788    return '999999';
789  }
790}
791export default function matchRegexsTest() {
792  describe('matchRegexsTest', () => {
793    it('testMockfunc', 0, () => {
794      console.info("it1 begin");
795      // 1.创建一个mock能力的对象MockKit
796      let mocker: MockKit = new MockKit();
797      let claser: ClassName = new ClassName();
798      // 2.进行mock操作,比如需要对ClassName类的method_1函数进行mock
799      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
800      // 3.期望claser.method_1函数被mock后, 以"test"为入参调用函数时返回结果'1'
801      when(mockfunc)(ArgumentMatchers.matchRegexs(new RegExp("test"))).afterReturn('1');
802      // 4.对mock后的函数进行断言,看是否符合预期,注意选择跟第4步中对应的断言方法
803      // 执行成功的案例,传参为字符串类型
804      expect(claser.method_1('test')).assertEqual('1'); // 用例执行通过。
805    })
806  })
807}
808```
809
810**示例6: 验证功能 Verify函数的使用**
811```javascript
812import { describe, it, MockKit } from '@ohos/hypium';
813
814class ClassName {
815  constructor() {
816  }
817
818  method_1(...arg: string[]) {
819    return '888888';
820  }
821
822  method_2(...arg: string[]) {
823    return '999999';
824  }
825}
826export default function verifyTest() {
827  describe('verifyTest', () => {
828    it('testMockfunc', 0, () => {
829      console.info("it1 begin");
830      // 1.创建一个mock能力的对象MockKit
831      let mocker: MockKit = new MockKit();
832      // 2.然后创建一个对象claser
833      let claser: ClassName = new ClassName();
834      // 3.进行mock操作,比如需要对ClassName类的method_1和method_2两个函数进行mock
835      mocker.mockFunc(claser, claser.method_1);
836      mocker.mockFunc(claser, claser.method_2);
837      // 4.方法调用如下
838      claser.method_1('abc', 'ppp');
839      claser.method_1('abc');
840      claser.method_1('xyz');
841      claser.method_1();
842      claser.method_1('abc', 'xxx', 'yyy');
843      claser.method_1();
844      claser.method_2('111');
845      claser.method_2('111', '222');
846      // 5.现在对mock后的两个函数进行验证,验证method_2,参数为'111'执行过一次
847      mocker.verify('method_2',['111']).once(); // 执行success
848    })
849  })
850}
851```
852
853**示例7: ignoreMock(obj, method) 忽略函数的使用**
854```javascript
855import { describe, expect, it, MockKit, when, ArgumentMatchers } from '@ohos/hypium';
856
857class ClassName {
858  constructor() {
859  }
860
861  method_1(...arg: number[]) {
862    return '888888';
863  }
864
865  method_2(...arg: number[]) {
866    return '999999';
867  }
868}
869export default function ignoreMockTest() {
870  describe('ignoreMockTest', () => {
871    it('testMockfunc', 0, () => {
872      console.info("it1 begin");
873      // 1.创建一个mock能力的对象MockKit
874      let mocker: MockKit = new MockKit();
875      // 2.创建一个对象claser
876      let claser: ClassName = new ClassName();
877      // 3.进行mock操作,比如需要对ClassName类的method_1和method_2两个函数进行mock
878      let func_1: Function = mocker.mockFunc(claser, claser.method_1);
879      let func_2: Function = mocker.mockFunc(claser, claser.method_2);
880      // 4.期望claser.method_1函数被mock后, 以number类型为入参时调用函数返回结果'4'
881      when(func_1)(ArgumentMatchers.anyNumber).afterReturn('4');
882      // 4.期望claser.method_2函数被mock后, 以number类型为入参时调用函数返回结果'5'
883      when(func_2)(ArgumentMatchers.anyNumber).afterReturn('5');
884      // 5.方法调用如下
885      expect(claser.method_1(123)).assertEqual("4");
886      expect(claser.method_2(456)).assertEqual("5");
887      // 6.现在对mock后的两个函数的其中一个函数method_1进行忽略处理(原理是就是还原)
888      mocker.ignoreMock(claser, claser.method_1);
889      // 7.然后再去调用 claser.method_1函数,用断言测试結果
890      expect(claser.method_1(123)).assertEqual('888888');
891    })
892  })
893}
894```
895
896**示例8: clear(obj)函数的使用**
897
898```javascript
899import { describe, expect, it, MockKit, when, ArgumentMatchers } from '@ohos/hypium';
900
901class ClassName {
902  constructor() {
903  }
904
905  method_1(...arg: number[]) {
906    return '888888';
907  }
908
909  method_2(...arg: number[]) {
910    return '999999';
911  }
912}
913export default function clearTest() {
914  describe('clearTest', () => {
915    it('testMockfunc', 0, () => {
916      console.info("it1 begin");
917      // 1.创建一个mock能力的对象MockKit
918      let mocker: MockKit = new MockKit();
919      // 2.创建一个对象claser
920      let claser: ClassName = new ClassName();
921      // 3.进行mock操作,比如需要对ClassName类的method_1和method_2两个函数进行mock
922      let func_1: Function = mocker.mockFunc(claser, claser.method_1);
923      let func_2: Function = mocker.mockFunc(claser, claser.method_2);
924      // 4.期望claser.method_1函数被mock后, 以任何number类型为参数调用函数时返回结果'4'
925      when(func_1)(ArgumentMatchers.anyNumber).afterReturn('4');
926      // 4.期望claser.method_2函数被mock后, 以任何number类型为参数调用函数时返回结果'5'
927      when(func_2)(ArgumentMatchers.anyNumber).afterReturn('5');
928      // 5.方法调用如下
929      expect(claser.method_1(123)).assertEqual('4');
930      expect(claser.method_2(123)).assertEqual('5');
931      // 6.清除obj上所有的mock能力(原理是就是还原)
932      mocker.clear(claser);
933      // 7.然后再去调用 claser.method_1,claser.method_2 函数,测试结果
934      expect(claser.method_1(123)).assertEqual('888888');
935      expect(claser.method_2(123)).assertEqual('999999');
936    })
937  })
938}
939```
940
941**示例9: afterThrow(msg)函数的使用**
942
943```javascript
944import { describe, expect, it, MockKit, when } from '@ohos/hypium';
945
946class ClassName {
947  constructor() {
948  }
949
950  method_1(arg: string) {
951    return '888888';
952  }
953}
954export default function afterThrowTest() {
955  describe('afterThrowTest', () => {
956    it('testMockfunc', 0, () => {
957      console.info("it1 begin");
958      // 1.创建一个mock能力的对象MockKit
959      let mocker: MockKit = new MockKit();
960      // 2.创建一个对象claser
961      let claser: ClassName = new ClassName();
962      // 3.进行mock操作,比如需要对ClassName类的method_1函数进行mock
963      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
964      // 4.期望claser.method_1函数被mock后, 以'test'为参数调用函数时抛出error xxx异常
965      when(mockfunc)('test').afterThrow('error xxx');
966      // 5.执行mock后的函数,捕捉异常并使用assertEqual对比msg否符合预期
967      try {
968        claser.method_1('test');
969      } catch (e) {
970        expect(e).assertEqual('error xxx'); // 执行通过
971      }
972    })
973  })
974}
975```
976
977**示例10: mock异步返回promise对象的使用**
978
979```javascript
980import { describe, expect, it, MockKit, when } from '@ohos/hypium';
981
982class ClassName {
983  constructor() {
984  }
985
986  async method_1(arg: string) {
987    return new Promise<string>((resolve: Function, reject: Function) => {
988      setTimeout(() => {
989        console.log('执行');
990        resolve('数据传递');
991      }, 2000);
992    });
993  }
994}
995export default function mockPromiseTest() {
996  describe('mockPromiseTest', () => {
997    it('testMockfunc', 0, async (done: Function) => {
998      console.info("it1 begin");
999      // 1.创建一个mock能力的对象MockKit
1000      let mocker: MockKit = new MockKit();
1001      // 2.创建一个对象claser
1002      let claser: ClassName = new ClassName();
1003      // 3.进行mock操作,比如需要对ClassName类的method_1函数进行mock
1004      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
1005      // 4.期望claser.method_1函数被mock后, 以'test'为参数调用函数时返回一个promise对象
1006      when(mockfunc)('test').afterReturn(new Promise<string>((resolve: Function, reject: Function) => {
1007        console.log("do something");
1008        resolve('success something');
1009      }));
1010      // 5.执行mock后的函数,即对定义的promise进行后续执行
1011      let result = await claser.method_1('test');
1012      expect(result).assertEqual("success something");
1013      done();
1014    })
1015  })
1016}
1017```
1018
1019**示例11:verify times函数的使用(验证函数调用次数)**
1020
1021```javascript
1022import { describe, it, MockKit, when } from '@ohos/hypium'
1023
1024class ClassName {
1025  constructor() {
1026  }
1027
1028  method_1(...arg: string[]) {
1029    return '888888';
1030  }
1031}
1032export default function verifyTimesTest() {
1033  describe('verifyTimesTest', () => {
1034    it('test_verify_times', 0, () => {
1035      // 1.创建MockKit对象
1036      let mocker: MockKit = new MockKit();
1037      // 2.创建类对象
1038      let claser: ClassName = new ClassName();
1039      // 3.mock 类ClassName对象的某个方法,比如method_1
1040      let func_1: Function = mocker.mockFunc(claser, claser.method_1);
1041      // 4.期望被mock后的函数返回结果'4'
1042      when(func_1)('123').afterReturn('4');
1043      // 5.随机执行几次函数,参数如下
1044      claser.method_1('123', 'ppp');
1045      claser.method_1('abc');
1046      claser.method_1('xyz');
1047      claser.method_1();
1048      claser.method_1('abc', 'xxx', 'yyy');
1049      claser.method_1('abc');
1050      claser.method_1();
1051      // 6.验证函数method_1且参数为'abc'时,执行过的次数是否为2
1052      mocker.verify('method_1', ['abc']).times(2);
1053    })
1054  })
1055}
1056```
1057
1058
1059**示例12:verify atLeast函数的使用(验证函数调用次数)**
1060
1061```javascript
1062import { describe, it, MockKit, when } from '@ohos/hypium'
1063
1064class ClassName {
1065  constructor() {
1066  }
1067
1068  method_1(...arg: string[]) {
1069    return '888888';
1070  }
1071}
1072export default function verifyAtLeastTest() {
1073  describe('verifyAtLeastTest', () => {
1074    it('test_verify_atLeast', 0, () => {
1075      // 1.创建MockKit对象
1076      let mocker: MockKit = new MockKit();
1077      // 2.创建类对象
1078      let claser: ClassName = new ClassName();
1079      // 3.mock  类ClassName对象的某个方法,比如method_1
1080      let func_1: Function = mocker.mockFunc(claser, claser.method_1);
1081      // 4.期望被mock后的函数返回结果'4'
1082      when(func_1)('123').afterReturn('4');
1083      // 5.随机执行几次函数,参数如下
1084      claser.method_1('123', 'ppp');
1085      claser.method_1('abc');
1086      claser.method_1('xyz');
1087      claser.method_1();
1088      claser.method_1('abc', 'xxx', 'yyy');
1089      claser.method_1();
1090      // 6.验证函数method_1且参数为空时,是否至少执行过2次
1091      mocker.verify('method_1', []).atLeast(2);
1092    })
1093  })
1094}
1095```
1096
1097**示例13:mock静态函数**
1098> @since1.0.16 支持
1099
1100```javascript
1101import { describe, it, expect, MockKit, when, ArgumentMatchers } from '@ohos/hypium';
1102
1103class ClassName {
1104  constructor() {
1105  }
1106
1107  static method_1() {
1108    return 'ClassName_method_1_call';
1109  }
1110}
1111
1112export default function staticTest() {
1113  describe('staticTest', () => {
1114    it('staticTest_001', 0, () => {
1115      let really_result = ClassName.method_1();
1116      expect(really_result).assertEqual('ClassName_method_1_call');
1117      // 1.创建MockKit对象
1118      let mocker: MockKit = new MockKit();
1119      // 2.mock  类ClassName对象的某个方法,比如method_1
1120      let func_1: Function = mocker.mockFunc(ClassName, ClassName.method_1);
1121      // 3.期望被mock后的函数返回结果'mock_data'
1122      when(func_1)(ArgumentMatchers.any).afterReturn('mock_data');
1123      let mock_result = ClassName.method_1();
1124      expect(mock_result).assertEqual('mock_data');
1125      // 清除mock能力
1126      mocker.clear(ClassName);
1127      let really_result1 = ClassName.method_1();
1128      expect(really_result1).assertEqual('ClassName_method_1_call');
1129    })
1130  })
1131}
1132```
1133
1134#### 数据驱动
1135
1136##### 约束限制
1137
1138单元测试框架数据驱动能力从[框架 1.0.2版本](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fhypium)开始支持。
1139
1140- 数据参数传递 : 为指定测试套、测试用例传递测试输入数据参数。
1141- 压力测试 : 为指定测试套、测试用例设置执行次数。
1142
1143数据驱动可以根据配置参数来驱动测试用例的执行次数和每一次传入的参数,使用时依赖data.json配置文件,文件内容如下:
1144
1145>说明 : data.json与测试用例*.test.js|ets文件同目录
1146
1147```json
1148{
1149	"suites": [{
1150		"describe": ["actsAbilityTest"],
1151		"stress": 2,
1152		"params": {
1153			"suiteParams1": "suiteParams001",
1154			"suiteParams2": "suiteParams002"
1155		},
1156		"items": [{
1157			"it": "testDataDriverAsync",
1158			"stress": 2,
1159			"params": [{
1160				"name": "tom",
1161				"value": 5
1162			}, {
1163				"name": "jerry",
1164				"value": 4
1165			}]
1166		}, {
1167			"it": "testDataDriver",
1168			"stress": 3
1169		}]
1170	}]
1171}
1172```
1173
1174配置参数说明:
1175
1176|      | 配置项名称 | 功能                                  | 必填 |
1177| :--- | :--------- | :------------------------------------ | ---- |
1178| 1    | "suite"    | 测试套配置 。                         | 是   |
1179| 2    | "items"    | 测试用例配置 。                       | 是   |
1180| 3    | "describe" | 测试套名称 。                         | 是   |
1181| 4    | "it"       | 测试用例名称 。                       | 是   |
1182| 5    | "params"   | 测试套 / 测试用例 可传入使用的参数 。 | 否   |
1183| 6    | "stress"   | 测试套 / 测试用例 指定执行次数 。     | 否   |
1184
1185示例代码:
1186
1187DevEco Studio从V3.0 Release(2022-09-06)版本开始支持
1188
1189stage模型:
1190
1191在TestAbility目录下TestAbility.ets文件中导入data.json,并在Hypium.hypiumTest() 方法执行前,设置参数数据
1192
1193FA模型:
1194
1195在TestAbility目录下app.jsapp.ets文件中导入data.json,并在Hypium.hypiumTest() 方法执行前,设置参数数据
1196
1197```javascript
1198import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
1199import { Hypium } from '@ohos/hypium'
1200import testsuite from '../test/List.test'
1201import data from '../test/data.json';
1202
1203...
1204Hypium.setData(data);
1205Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
1206...
1207```
1208
1209```javascript
1210 import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
1211
1212 export default function abilityTest() {
1213  describe('actsAbilityTest', () => {
1214    it('testDataDriverAsync', 0, async (done: Function, data: ParmObj) => {
1215      console.info('name: ' + data.name);
1216      console.info('value: ' + data.value);
1217      done();
1218    });
1219
1220    it('testDataDriver', 0, () => {
1221      console.info('stress test');
1222    })
1223  })
1224}
1225 interface ParmObj {
1226   name: string,
1227   value: string
1228 }
1229```
1230>说明 : 若要使用数据驱动传入参数功能,测试用例it的func必须传入两个参数:done定义在前面,data定义在后面;若不使用数据驱动传入参数功能,func可以不传参或传入done
1231
1232正确示例:
1233```javascript
1234    it('testcase01', 0, async (done: Function, data: ParmObj) => {
1235      ...
1236      done();
1237    });
1238    it('testcase02', 0, async (done: Function) => {
1239      ...
1240      done();
1241    });
1242    it('testcase03', 0, () => {
1243      ...
1244    });
1245```
1246错误示例:
1247```javascript
1248    it('testcase01', 0, async (data: ParmObj, done: Function) => {
1249      ...
1250      done();
1251    });
1252    it('testcase02', 0, async (data: ParmObj) => {
1253      ...
1254    });
1255```
1256
1257#### 专项能力
1258
1259该项能力需通过在cmd窗口中输入aa test命令执行触发,并通过设置执行参数触发不同功能。另外,测试应用模型与编译方式不同,对应的aa test命令也不同,具体可参考[自动化测试框架使用指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-test/arkxtest-guidelines.md#cmd%E6%89%A7%E8%A1%8C)
1260
1261- **筛选能力**
1262
1263  1、按测试用例属性筛选
1264
1265  可以利用框架提供的Level、Size、TestType 对象,对测试用例进行标记,以区分测试用例的级别、粒度、测试类型,各字段含义及代码如下:
1266
1267  | Key      | 含义说明     | Value取值范围                                                                                                                                          |
1268  | -------- | ------------ |----------------------------------------------------------------------------------------------------------------------------------------------------|
1269  | level    | 用例级别     | "0","1","2","3","4", 例如:-s level 1                                                                                                                 |
1270  | size     | 用例粒度     | "small","medium","large", 例如:-s size small                                                                                                         |
1271  | testType | 用例测试类型 | "function","performance","power","reliability","security","global","compatibility","user","standard","safety","resilience", 例如:-s testType function |
1272
1273  示例代码:
1274
1275 ```javascript
1276 import { describe, it, expect, TestType, Size, Level } from '@ohos/hypium';
1277
1278 export default function attributeTest() {
1279  describe('attributeTest', () => {
1280    it("testAttributeIt", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, () => {
1281      console.info('Hello Test');
1282    })
1283  })
1284}
1285 ```
1286
1287  示例命令:
1288
1289  ```shell
1290  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s testType function -s size small -s level 0
1291  ```
1292
1293  该命令作用是筛选测试应用中同时满足,用例测试类型是“function”、用例粒度是“small”、用例级别是“0”的三个条件用例执行。
1294
1295  2、按测试套/测试用例名称筛选
1296
1297  注意:测试套和测试用例的命名要符合框架规则,即以字母开头,后跟一个或多个字母、数字,不能包含特殊符号。
1298
1299  框架可以通过指定测试套与测试用例名称,来指定特定用例的执行,测试套与用例名称用“#”号连接,多个用“,”英文逗号分隔
1300
1301  | Key      | 含义说明                | Value取值范围                                                |
1302  | -------- | ----------------------- | ------------------------------------------------------------ |
1303  | class    | 指定要执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s class attributeTest#testAttributeIt |
1304  | notClass | 指定不执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s notClass attributeTest#testAttribut |
1305
1306  示例代码:
1307
1308  ```javascript
1309  import { describe, it, expect, TestType, Size, Level } from '@ohos/hypium';
1310
1311  export default function attributeTest() {
1312  describe('describeTest_000',  () => {
1313    it("testIt_00", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0,  () => {
1314      console.info('Hello Test');
1315    })
1316
1317    it("testIt_01", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, () => {
1318      console.info('Hello Test');
1319    })
1320  })
1321
1322  describe('describeTest_001',  () => {
1323    it("testIt_02", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, () => {
1324      console.info('Hello Test');
1325    })
1326  })
1327}
1328  ```
1329
1330  示例命令1:
1331
1332  ```shell
1333  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s class describeTest_000#testIt_00,describeTest_001
1334  ```
1335
1336  该命令作用是执行“describeTest_001”测试套中所有用例,以及“describeTest_000”测试套中的“testIt_00”用例。
1337
1338  示例命令2:
1339
1340  ```shell
1341  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s notClass describeTest_000#testIt_01
1342  ```
1343
1344  该命令作用是不执行“describeTest_000”测试套中的“testIt_01”用例。
1345
1346- **随机执行**
1347
1348  使测试套与测试用例随机执行,用于稳定性测试。
1349
1350  | Key    | 含义说明                             | Value取值范围                                  |
1351  | ------ | ------------------------------------ | ---------------------------------------------- |
1352  | random | @since1.0.3 测试套、测试用例随机执行 | true, 不传参默认为false, 例如:-s random true |
1353
1354  示例命令:
1355
1356  ```shell
1357  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s random true
1358  ```
1359
1360- **压力测试**
1361
1362  指定要执行用例的执行次数,用于压力测试。
1363
1364  | Key    | 含义说明                             | Value取值范围                  |
1365  | ------ | ------------------------------------ | ------------------------------ |
1366  | stress | @since1.0.5 指定要执行用例的执行次数 | 正整数, 例如: -s stress 1000 |
1367
1368  示例命令:
1369
1370  ```shell
1371  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s stress 1000
1372  ```
1373
1374- **用例超时时间设置**
1375
1376  指定测试用例执行的超时时间,用例实际耗时如果大于超时时间,用例会抛出"timeout"异常,用例结果会显示“excute timeout XXX”
1377
1378  | Key     | 含义说明                   | Value取值范围                                        |
1379  | ------- | -------------------------- | ---------------------------------------------------- |
1380  | timeout | 指定测试用例执行的超时时间 | 正整数(单位ms),默认为 5000,例如: -s timeout 15000 |
1381
1382  示例命令:
1383
1384  ```shell
1385  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s timeout 15000
1386  ```
1387
1388- **遇错即停模式**
1389
1390  | Key          | 含义说明                                                     | Value取值范围                                        |
1391  | ------------ | ------------------------------------------------------------ | ---------------------------------------------------- |
1392  | breakOnError | @since1.0.6 遇错即停模式,当执行用例断言失败或者发生错误时,退出测试执行流程 | true, 不传参默认为false, 例如:-s breakOnError true |
1393
1394  示例命令:
1395
1396  ```shell
1397  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s breakOnError true
1398  ```
1399
1400- **测试套中用例信息输出**
1401
1402  输出测试应用中待执行的测试用例信息
1403
1404  | Key    | 含义说明                     | Value取值范围                                  |
1405  | ------ | ---------------------------- | ---------------------------------------------- |
1406  | dryRun | 显示待执行的测试用例信息全集 | true, 不传参默认为false, 例如:-s dryRun true |
1407
1408  示例命令:
1409
1410  ```shell
1411  hdc shell aa test -b xxx -m xxx -s unittest OpenHarmonyTestRunner -s dryRun true
1412  ```
1413
1414- **嵌套能力**
1415
1416  1.示例代码
1417  ```javascript
1418  // Test1.test.ets
1419  import { describe, expect, it } from '@ohos/hypium';
1420  import test2 from './Test2.test';
1421
1422  export default function test1() {
1423    describe('test1', () => {
1424      it('assertContain1', 0, () => {
1425        let a = true;
1426        let b = true;
1427        expect(a).assertEqual(b);
1428      })
1429      // 引入测试套test2
1430      test2();
1431    })
1432  }
1433  ```
1434
1435  ```javascript
1436  //Test2.test.ets
1437  import { describe, expect, it } from '@ohos/hypium';
1438
1439  export default function test2() {
1440    describe('test2', () => {
1441      it('assertContain1', 0, () => {
1442        let a = true;
1443        let b = true;
1444        expect(a).assertEqual(b);
1445      })
1446      it('assertContain2', 0, () => {
1447        let a = true;
1448        let b = true;
1449        expect(a).assertEqual(b);
1450      })
1451    })
1452  }
1453  ```
1454
1455  ```javascript
1456  //List.test.ets
1457  import test1 from './nest/Test1.test';
1458
1459  export default function testsuite() {
1460    test1();
1461  }
1462  ```
1463
1464  2.示例筛选参数
1465    ```shell
1466    #执行test1的全部测试用例
1467    -s class test1
1468    ```
1469    ```shell
1470    #执行test1的子测试用例
1471    -s class test1#assertContain1
1472    ```
1473    ```shell
1474    #执行test1的子测试套test2的测试用例
1475    -s class test1.test2#assertContain1
1476    ```
1477
1478- **跳过能力**
1479
1480    | Key          | 含义说明                                                     | Value取值范围                                        |
1481  | ------------ | ------------------------------------------------------------ | ---------------------------------------------------- |
1482  | skipMessage | @since1.0.17 显示待执行的测试用例信息全集中是否包含跳过测试套和跳过用例的信息 | true/false, 不传参默认为false, 例如:-s skipMessage true |
1483  | runSkipped | @since1.0.17 指定要执行的跳过测试套&跳过用例 | all,skipped,${describeName}#${itName},${describeName},不传参默认为空,例如:-s runSkipped all |
1484
1485  1.示例代码
1486
1487  ```javascript
1488  //Skip1.test.ets
1489  import { expect, xdescribe, xit } from '@ohos/hypium';
1490
1491  export default function skip1() {
1492    xdescribe('skip1', () => {
1493      //注意:在xdescribe中不支持编写it用例
1494      xit('assertContain1', 0, () => {
1495        let a = true;
1496        let b = true;
1497        expect(a).assertEqual(b);
1498      })
1499    })
1500  }
1501  ```
1502
1503    ```javascript
1504  //Skip2.test.ets
1505  import { describe, expect, xit, it } from '@ohos/hypium';
1506
1507  export default function skip2() {
1508    describe('skip2', () => {
1509      //默认会跳过assertContain1
1510      xit('assertContain1', 0, () => {
1511        let a = true;
1512        let b = true;
1513        expect(a).assertEqual(b);
1514      })
1515      it('assertContain2', 0, () => {
1516        let a = true;
1517        let b = true;
1518        expect(a).assertEqual(b);
1519      })
1520    })
1521  }
1522    ```
1523
1524
1525
1526### 使用方式
1527
1528单元测试框架以ohpm包形式发布至[服务组件官网](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fhypium),开发者可以下载Deveco Studio后,在应用工程中配置依赖后使用框架能力,测试工程创建及测试脚本执行使用指南请参见[IDE指导文档](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453)1529>**说明**
1530>
1531>1.0.8版本开始单元测试框架以HAR(Harmony Archive)格式发布
1532>
1533>
1534
1535## Ui测试框架功能特性
1536
1537| No.  | 特性        | 功能说明                                            |
1538| ---- |-----------|-------------------------------------------------|
1539| 1    | Driver    | Ui测试的入口,提供查找控件,检查控件存在性以及注入按键能力。                 |
1540| 2    | On        | 用于描述目标控件特征(文本、id、类型等),`Driver`根据`On`描述的控件特征信息来查找控件。 |
1541| 3    | Component | Driver查找返回的控件对象,提供查询控件属性,滑动查找等触控和检视能力。          |
1542| 4    | UiWindow  | Driver查找返回的窗口对象,提供获取窗口属性、操作窗口的能力。               |
1543
1544**使用者在测试脚本通过如下方式引入使用:**
1545
1546```typescript
1547import {Driver,ON,Component,UiWindow,MatchPattern} from '@ohos.UiTest'
1548```
1549
1550> 须知
1551> 1. `On`类提供的接口全部是同步接口,使用者可以使用`builder`模式链式调用其接口构造控件筛选条件。
1552> 2. `Driver`和`Component`类提供的接口全部是异步接口(`Promise`形式),**需使用`await`语法**。
1553> 3. Ui测试用例均需使用**异步**语法编写用例,需遵循单元测试框架异步用例编写规范。
1554
1555
1556
1557在测试用例文件中import `On/Driver/Component`类,然后调用API接口编写测试用例。
1558
1559```javascript
1560import { Driver, ON, Component } from '@kit.TestKit'
1561import { describe, it, expect } from '@ohos/hypium'
1562
1563export default function findComponentTest() {
1564  describe('findComponentTest', () => {
1565    it('uitest_demo0', 0, async () => {
1566      // create Driver
1567      let driver: Driver = Driver.create();
1568      // find component by text
1569      let button: Component = await driver.findComponent(ON.text('Hello World').enabled(true));
1570      // click component
1571      await button.click();
1572      // get and assert component text
1573      let content: string = await button.getText();
1574      expect(content).assertEqual('Hello World');
1575    })
1576  })
1577}
1578```
1579
1580### 基于ArkTS API的测试
1581
1582
1583#### Driver使用说明
1584
1585`Driver`类作为UiTest测试框架的总入口,提供查找控件,注入按键,单击坐标,滑动控件,手势操作,截图等能力。
1586
1587| No.  | API                                                             | 功能描述               |
1588| ---- |-----------------------------------------------------------------| ---------------------- |
1589| 1    | create():Promise<Driver>                                        | 静态方法,构造Driver。 |
1590| 2    | findComponent(on:On):Promise<Component>                         | 查找匹配控件。         |
1591| 3    | pressBack():Promise<void>                                       | 单击BACK键。           |
1592| 4    | click(x:number, y:number):Promise<void>                         | 基于坐标点的单击。      |
1593| 5    | swipe(x1:number, y1:number, x2:number, y2:number):Promise<void> | 基于坐标点的滑动。      |
1594| 6    | assertComponentExist(on:On):Promise<void>                       | 断言匹配的控件存在。     |
1595| 7    | delayMs(t:number):Promise<void>                                 | 延时。                 |
1596| 8    | screenCap(s:path):Promise<void>                                 | 截屏。                 |
1597| 9    | findWindow(filter: WindowFilter): Promise<UiWindow>             | 查找匹配窗口。         |
1598
1599其中assertComponentExist接口是断言API,用于断言当前界面存在目标控件;如果控件不存在,该API将抛出JS异常,使当前测试用例失败。
1600
1601```javascript
1602import { describe, it} from '@ohos/hypium';
1603import { Driver, ON } from '@kit.TestKit';
1604
1605export default function assertComponentExistTest() {
1606  describe('assertComponentExistTest', () => {
1607    it('Uitest_demo0', 0, async (done: Function) => {
1608      try{
1609        // create Driver
1610        let driver: Driver = Driver.create();
1611        // assert text 'hello' exists on current Ui
1612        await driver.assertComponentExist(ON.text('hello'));
1613      } finally {
1614        done();
1615      }
1616    })
1617  })
1618}
1619```
1620
1621`Driver`完整的API列表请参考[API文档](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts)及[示例文档说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-test-kit/js-apis-uitest.md#driver9)1622
1623#### On使用说明
1624
1625Ui测试框架通过`On`类提供了丰富的控件特征描述API,用来匹配查找要操作或检视的目标控件。`On`提供的API能力具有以下特点:
1626
1627- 支持匹配单属性和匹配多属性组合,例如同时指定目标控件text和id。
1628- 控件属性支持多种匹配模式(等于,包含,`STARTS_WITH`,`ENDS_WITH`,`REG_EXP`,`REG_EXP_ICASE`)。
1629
1630- 支持相对定位控件,可通过`isBefore`和`isAfter`等API限定邻近控件特征进行辅助定位。
1631
1632| No. | API                                      | 功能描述                       |
1633|-----|------------------------------------------|----------------------------|
1634| 1   | id(i:string):On                          | 指定控件id。                    |
1635| 2   | text(t:string, p?:MatchPattern):On       | 指定控件文本,可指定匹配模式。            |
1636| 3   | type(t:string):On                        | 指定控件类型。                    |
1637| 4   | enabled(e:bool):On                       | 指定控件使能状态。                  |
1638| 5   | clickable(c:bool):On                     | 指定控件可单击状态。                 |
1639| 6   | longClickable(l:bool):On                 | 指定控件可长按状态。                 |
1640| 7   | focused(f:bool):On                       | 指定控件获焦状态。                  |
1641| 8   | scrollable(s:bool):On                    | 指定控件可滑动状态。                 |
1642| 9   | selected(s:bool):On                      | 指定控件选中状态。                  |
1643| 10  | checked(c:bool):On                       | 指定控件选择状态。                  |
1644| 11  | checkable(c:bool):On                     | 指定控件可选择状态。                 |
1645| 12  | isBefore(b:On):On                        | **相对定位**,限定目标控件位于指定特征控件之前。 |
1646| 13  | isAfter(b:On):On                         | **相对定位**,限定目标控件位于指定特征控件之后。 |
1647| 14   | id(i:string,p?:MatchPattern):On          | 指定控件id,可指定匹配模式。                    |
1648| 15   | hint(h:string, p?:MatchPattern):On       | 指定控件提示文本,可指定匹配模式。            |
1649| 16   | type(t:string,p?:MatchPattern):On        | 指定控件类型,可指定匹配模式。                   |
1650| 17   | description(d:string,p?:MatchPattern):On | 指定控件描述文本信息,可指定匹配模式。                   |
1651
1652其中,`text`,`id`,`type`,`hint`,`description`属性支持{`MatchPattern.EQUALS`,`MatchPattern.CONTAINS`,`MatchPattern.STARTS_WITH`,`MatchPattern.ENDS_WITH`,`MatchPattern.REG_EXP`,`MatchPattern.REG_EXP_ICASE`}六种匹配模式,缺省使用`MatchPattern.EQUALS`模式。
1653
1654`On`完整的API列表请参考[API文档](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts)及[示例文档说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-test-kit/js-apis-uitest.md#on9)1655
1656##### 控件定位
1657
1658**示例代码1**:查找id是`Id_button`的控件。
1659
1660```javascript
1661let button: Component = await driver.findComponent(ON.id('Id_button'))
1662```
1663
1664 **示例代码2**:查找id是`Id_button`并且状态是`enabled`的控件,适用于无法通过单一属性定位的场景。
1665
1666```javascript
1667let button: Component = await driver.findComponent(ON.id('Id_button').enabled(true))
1668```
1669
1670通过`On.id(x).enabled(y)`来指定目标控件的多个属性。
1671
1672**示例代码3**:查找文本中包含`hello`的控件,适用于不能完全确定控件属性取值的场景。
1673
1674```javascript
1675let txt: Component = await driver.findComponent(ON.text('hello', MatchPattern.CONTAINS))
1676```
1677
1678通过向`On.text()`方法传入第二个参数`MatchPattern.CONTAINS`来指定文本匹配规则;默认规则是`MatchPattern.EQUALS`,即目标控件text属性必须严格等于给定值。
1679
1680#####  控件相对定位
1681
1682**示例代码1**:查找位于文本控件`Item3_3`后面的,id是`Id_switch`的Switch控件。
1683
1684```javascript
1685let switch: Component = await driver.findComponent(ON.id('Id_switch').isAfter(ON.text('Item3_3')))
1686```
1687
1688通过`On.isAfter`方法,指定位于目标控件前面的特征控件属性,通过该特征控件进行相对定位。一般地,特征控件是某个具有全局唯一特征的控件(例如具有唯一的id或者唯一的text)。
1689
1690类似的,可以使用`On.isBefore`控件指定位于目标控件后面的特征控件属性,实现相对定位。
1691
1692#### Component使用说明
1693
1694`Component`类代表了Ui界面上的一个控件,一般是通过`Driver.findComponent(on)`方法查找到的。通过该类的实例,用户可以获取控件属性,单击控件,滑动查找,注入文本等操作。
1695
1696`Component`包含的常用API:
1697
1698| No. | API                                | 功能描述                       |
1699|-----|------------------------------------|----------------------------|
1700| 1   | click():Promise<void>              | 单击该控件。                     |
1701| 2   | inputText(t:string):Promise<void>  | 向控件中输入文本(适用于文本框控件)。        |
1702| 3   | scrollSearch(s:On):Promise<Component>   | 在该控件上滑动查找目标控件(适用于List等控件)。 |
1703| 4   | scrollToTop(s:number):Promise<void>    | 滑动到该控件顶部(适用于List等控件)。      |
1704| 5   | scrollTobottom(s:number):Promise<void> | 滑动到该控件底部(适用于List等控件)。      |
1705| 6   | getText():Promise<string>          | 获取控件text。                  |
1706| 7   | getId():Promise<number>            | 获取控件id。                    |
1707| 8   | getType():Promise<string>          | 获取控件类型。                    |
1708| 9   | isEnabled():Promise<bool>          | 获取控件使能状态。                  |
1709
1710`Component`完整的API列表请参考[API文档](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts)及[示例文档说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-test-kit/js-apis-uitest.md#component9)1711
1712**示例代码1**:单击控件。
1713
1714```javascript
1715let button: Component = await driver.findComponent(ON.id('Id_button'))
1716await button.click()
1717```
1718
1719**示例代码2**:通过get接口获取控件属性后,可以使用单元测试框架提供的assert*接口做断言检查。
1720
1721```javascript
1722let component: Component = await driver.findComponent(ON.id('Id_title'))
1723expect(component !== null).assertTrue()
1724```
1725
1726**示例代码3**:在List控件中滑动查找text是`Item3_3`的子控件。
1727
1728```javascript
1729let list: Component = await driver.findComponent(ON.id('Id_list'))
1730let found: Component = await list.scrollSearch(ON.text('Item3_3'))
1731expect(found).assertTrue()
1732```
1733
1734**示例代码4**:向输入框控件中输入文本。
1735
1736```javascript
1737let editText: Component = await driver.findComponent(ON.type('InputText'))
1738await editText.inputText('user_name')
1739```
1740#### UiWindow使用说明
1741
1742`UiWindow`类代表了Ui界面上的一个窗口,一般是通过`Driver.findWindow(WindowFilter)`方法查找到的。通过该类的实例,用户可以获取窗口属性,并进行窗口拖动、调整窗口大小等操作。
1743
1744`UiWindow`包含的常用API:
1745
1746| No.  | API                                                          | 功能描述                                           |
1747| ---- | ------------------------------------------------------------ | -------------------------------------------------- |
1748| 1    | getBundleName(): Promise<string>                             | 获取窗口所属应用包名。                             |
1749| 2    | getTitle(): Promise<string>                                  | 获取窗口标题信息。                                 |
1750| 3    | focus(): Promise<bool>                                       | 使得当前窗口获取焦点。                             |
1751| 4    | moveTo(x: number, y: number): Promise<bool>                  | 将当前窗口移动到指定位置(适用于支持移动的窗口)。 |
1752| 5    | resize(wide: number, height: number, direction: ResizeDirection): Promise<bool> | 调整窗口大小(适用于支持调整大小的窗口)。         |
1753| 6    | split(): Promise<bool>                                       | 将窗口模式切换为分屏模式(适用于支持分屏的窗口)。   |
1754| 7    | close(): Promise<bool>                                       | 关闭当前窗口。                                     |
1755
1756`UiWindow`完整的API列表请参考[API文档](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts)及[示例文档说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-test-kit/js-apis-uitest.md#uiwindow9)1757
1758**示例代码1**:获取窗口属性。
1759
1760```javascript
1761let window: UiWindow = await driver.findWindow({actived: true})
1762let bundelName: string = await window.getBundleName()
1763```
1764
1765**示例代码2**:移动窗口。
1766
1767```javascript
1768let window: UiWindow = await driver.findWindow({actived: true})
1769await window.moveTo(500,500)
1770```
1771
1772**示例代码3**:关闭窗口。
1773
1774```javascript
1775let window: UiWindow = await driver.findWindow({actived: true})
1776await window.close()
1777```
1778
1779#### 使用方式
1780
1781开发者可以下载Deveco Studio创建测试工程后,在其中调用框架提供接口进行相关测试操作,测试工程创建及测试脚本执行使用指南请参见[IDE指导文档](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001267284568)1782UI测试框架使能需要执行如下命令。
1783>**说明**
1784>
1785>OpenHarmony 3.2版本需使用此命令,OpenHarmony4.0版本开始无需使用,默认使能。
1786>
1787> hdc shell param set persist.ace.testmode.enabled 1。
1788
1789### 基于shell命令测试
1790> 在开发过程中,若需要快速进行截屏、 录屏、注入UI模拟操作、获取控件树等操作,可以使用shell命令,更方便完成相应测试。
1791>
1792> **说明:**
1793>
1794> 使用cmd的方式,需要配置好hdc相关的环境变量。
1795
1796**命令列表**
1797
1798| 命令            | 配置参数   | 描述                                                                                                                                                                                                                                                                  |
1799|---------------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1800| help          |  | 显示uitest工具能够支持的命令信息。                                                                                                                                                                                                                                                |
1801| screenCap       |[-p savePath] | 截屏。<br> **-p**:指定存储路径和文件名, 只支持存放在/data/local/tmp/下。<br>         默认存储路径:/data/local/tmp,文件名:时间戳 + .png 。                                                                                                                                                        |
1802| dumpLayout      |[-p  savePath] <br/>[-w  windowId] <br/>[-b bundleName]<br/>[-m true/false ]<br/>[-i ]<br/>[-a]| 获取当前的控件树。默认过滤不可见控件并进行窗口合并。<br> **-p** :指定存储路径和文件名, 只支持存放在/data/local/tmp/下。<br/>          默认存储路径:/data/local/tmp,文件名:时间戳 + .json。<br> **-w** :仅获取指定windowId的应用窗口。<br/> **-b** :仅获取指定bundleName的应用窗口。<br/> **-m** :是否进行窗口合并。true 代表进行合并,不使用该选项时默认进行窗口合并。<br/> **-i** :不过滤不可见控件,也不做窗口合并。<br/> **-a** :保存 BackgroundColor、 Content、FontColor、FontSize、extraAttrs 属性数据。<br/> **-a和-i** 不可同时使用。 |
1803| uiRecord        | \<record/read> | 录制Ui操作。  <br> **record** :开始录制,将当前界面操作记录到/data/local/tmp/record.csv,结束录制操作使用Ctrl+C结束录制。  <br> **read** :读取并且打印录制数据。<br>各选项使用说明请参考[用户录制操作](#用户录制操作)。                                                                                                        |
1804| uiInput       | \<help / click / doubleClick / longClick / fling / swipe / drag / dircFling / inputText / text  / keyEvent> | 注入UI模拟操作。<br>各选项使用说明请参考[注入ui模拟操作](#注入ui模拟操作)。                   |
1805| --version |  | 获取当前工具版本号。                                                                                                                                                                                                                                                        |
1806| start-daemon|\<token>| token:测试应用端生产的uitest链接标识。<br/>拉起uitest测试进程,与token指向的测试应用进行连接。<br/>由测试应用注入,不支持用户通过shell命令使用。                                                                                                                                                            |
1807
1808
1809#### 截图使用示例
1810
1811```bash
1812# 存储路径:/data/local/tmp,文件名:时间戳 + .png。
1813hdc shell uitest screenCap
1814# 指定存储路径和文件名,存放在/data/local/tmp/下。
1815hdc shell uitest screenCap -p /data/local/tmp/1.png
1816```
1817
1818#### 获取控件树使用示例
1819```bash
1820hdc shell uitest dumpLayout -p /data/local/tmp/1.json
1821```
1822
1823#### 用户录制操作
1824>**说明**
1825>
1826> 录制过程中,需等待当前操作的识别结果在命令行输出后,再进行下一步操作。
1827```bash
1828# 将当前界面操作记录到/data/local/tmp/record.csv,结束录制操作使用Ctrl+C结束录制。
1829hdc shell uitest uiRecord record
1830# 读取并打印录制数据。
1831hdc shell uitest uiRecord read
1832```
1833
1834#### 注入UI模拟操作
1835
1836| 命令   | 必填 | 描述              |
1837|------|------|-----------------|
1838| help   | 是    | uiInput命令相关帮助信息。 |
1839| click   | 是    | 模拟单击操作。      |
1840| doubleClick   | 是    | 模拟双击操作。      |
1841| longClick   | 是    | 模拟长按操作。     |
1842| fling   | 是    | 模拟快滑操作。   |
1843| swipe   | 是    | 模拟慢滑操作。     |
1844| drag   | 是    | 模拟拖拽操作。     |
1845| dircFling   | 是    | 模拟指定方向滑动操作。     |
1846| inputText   | 是    | 指定坐标点,模拟输入框输入文本操作。     |
1847| text | 是    | 无需指定坐标点,在当前获焦处,模拟输入框输入文本操作。     |
1848| keyEvent   | 是    | 模拟实体按键事件(如:键盘,电源键,返回上一级,返回桌面等),以及组合按键操作。     |
1849
1850##### uiInput click/doubleClick/longClick使用示例
1851
1852| 配置参数    | 必填 | 描述            |
1853|---------|------|-----------------|
1854| point_x | 是      | 点击x坐标点。 |
1855| point_y | 是       | 点击y坐标点。 |
1856
1857```shell
1858# 执行单击事件。
1859hdc shell uitest uiInput click 100 100
1860
1861# 执行双击事件。
1862hdc shell uitest uiInput doubleClick 100 100
1863
1864# 执行长按事件。
1865hdc shell uitest uiInput longClick 100 100
1866```
1867
1868##### uiInput fling使用示例
1869
1870| 配置参数  | 必填             | 描述               |
1871|------|------------------|-----------------|
1872| from_x   | 是                | 滑动起点x坐标。 |
1873| from_y   | 是                | 滑动起点y坐标。 |
1874| to_x   | 是                | 滑动终点x坐标。 |
1875| to_y   | 是                | 滑动终点y坐标。 |
1876| swipeVelocityPps_   | 否      | 滑动速度,单位: (px/s),取值范围:200-40000。<br> 默认值: 600。 |
1877| stepLength_   | 否 | 滑动步长。默认值: 滑动距离/50。<br>  **为实现更好的模拟效果,推荐参数缺省/使用默认值。**  |
1878
1879
1880```shell
1881# 执行快滑操作,stepLength_缺省。
1882hdc shell uitest uiInput fling 10 10 200 200 500
1883```
1884
1885##### uiInput swipe/drag使用示例
1886
1887| 配置参数  | 必填             | 描述               |
1888|------|------------------|-----------------|
1889| from_x   | 是                | 滑动起点x坐标。 |
1890| from_y   | 是                | 滑动起点y坐标。 |
1891| to_x   | 是                | 滑动终点x坐标。 |
1892| to_y   | 是                | 滑动终点y坐标。 |
1893| swipeVelocityPps_   | 否      | 滑动速度,单位: (px/s),取值范围:200-40000。<br> 默认值: 600。 |
1894
1895```shell
1896# 执行慢滑操作。
1897hdc shell uitest uiInput swipe 10 10 200 200 500
1898
1899# 执行拖拽操作。
1900hdc shell uitest uiInput drag 10 10 100 100 500
1901```
1902
1903##### uiInput dircFling使用示例
1904
1905| 配置参数             | 必填       | 描述 |
1906|-------------------|-------------|----------|
1907| direction         | 否 | 滑动方向,取值范围:[0,1,2,3],默认值为0。<br> 0代表向左滑动,1代表向右滑动,2代表向上滑动,3代表向下滑动。    |
1908| swipeVelocityPps_ | 否| 滑动速度,单位: (px/s),取值范围:200-40000。<br> 默认值: 600。    |
1909| stepLength        | 否        | 滑动步长。<br> 默认值: 滑动距离/50。为更好的模拟效果,推荐参数缺省/使用默认值。 |
1910
1911```shell
1912# 执行左滑操作
1913hdc shell uitest uiInput dircFling 0 500
1914# 执行向右滑动操作
1915hdc shell uitest uiInput dircFling 1 600
1916# 执行向上滑动操作。
1917hdc shell uitest uiInput dircFling 2
1918# 执行向下滑动操作。
1919hdc shell uitest uiInput dircFling 3
1920```
1921
1922##### uiInput inputText使用示例
1923
1924| 配置参数             | 必填       | 描述 |
1925|------|------------------|----------|
1926| point_x   | 是                | 输入框x坐标点。 |
1927| point_y   | 是                | 输入框y坐标点。 |
1928| text   | 是                | 输入文本内容。  |
1929
1930```shell
1931# 执行输入框输入操作。
1932hdc shell uitest uiInput inputText 100 100 hello
1933```
1934
1935##### uiInput text使用示例
1936| 配置参数             | 必填       | 描述 |
1937|------|------------------|----------|
1938| text   | 是                | 输入文本内容。  |
1939
1940```shell
1941# 无需输入坐标点,在当前获焦处,执行输入框输入操作。若当前获焦处不支持文本输入,则无实际效果。
1942hdc shell uitest uiInput text hello
1943```
1944
1945##### uiInput keyEvent使用示例
1946
1947| 配置参数             | 必填       | 描述 |
1948|------|------|----------|
1949| keyID1   | 是    | 实体按键对应ID,取值范围:KeyCode/Back/Home/Power。<br>当取Back/Home/Power时,不支持输入组合键。 |
1950| keyID2    | 否    | 实体按键对应ID。 |
1951| keyID3    | 否    | 实体按键对应ID。 |
1952
1953>**说明**
1954>
1955> 最多支持传入是三个键值,具体取值请参考[KeyCode](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-input-kit/js-apis-keycode.md)1956
1957```shell
1958# 执行执行返回主页操作。
1959hdc shell uitest uiInput keyEvent Home
1960# 执行返回操作。
1961hdc shell uitest uiInput keyEvent Back
1962# 执行组合键粘贴操作。
1963hdc shell uitest uiInput keyEvent 2072 2038
1964```
1965
1966#### 获取版本信息
1967
1968```bash
1969hdc shell uitest --version
1970```
1971#### 拉起uitest测试进程
1972
1973```shell
1974hdc shell uitest start-daemon
1975```
1976
1977### UI测试框架自构建方式
1978
1979#### 构建命令
1980
1981```shell
1982./build.sh --product-name rk3568 --build-target uitestkit
1983```
1984#### 推送位置
1985
1986```shell
1987hdc target mount
1988hdc shell mount -o rw,remount /
1989hdc file send uitest /system/bin/uitest
1990hdc file send libuitest.z.so /system/lib/module/libuitest.z.so
1991hdc shell chmod +x /system/bin/uitest
1992```
1993
1994## 版本信息
1995
1996| 版本号  | 功能说明                                                     |
1997| :------ | :----------------------------------------------------------- |
1998| 3.2.2.1 | 1、增加抛滑、获取/设置屏幕方向接口<br />2、窗口处理逻辑增加不支持场景处理逻辑。  |
1999| 3.2.3.0 | 1、滑动控件进行滑动查找、滑动到尾部/顶部功能优化。              |
2000| 3.2.4.0 | 1、接口调用异常时会抛出错误码。                                 |
2001| 3.2.5.0 | 1、通信机制变更。                                               |
2002| 3.2.6.0 | 1、增加模拟鼠标操作能力接口<br />2、增加指定应用的窗口下查找目标控件接口。  |
2003| 4.0.1.1 | 1、支持在daemon运行时执行uitest dumpLayout。                    |
2004| 4.0.1.2 | 1、模拟鼠标动作、键鼠协同功能优化。                             |
2005| 4.0.1.3 | 1、示例代码更新<br />2、滑动控件进行滑动查找、滑动到尾部/顶部功能优化。  |
2006| 4.0.1.4 | 1、可选参数传入undefined时,当作默认值处理。                    |
2007| 4.0.2.0 | 1、支持监听toast和dialog控件出现,使用callback的形式返回结果。 |
2008| 4.0.3.0 | 1、增加加载运行.abc文件机制。                                |
2009| 4.0.4.0 | 1、支持abc_loader框架获取UI操作录制数据,屏幕数据,控件树等,并以callback的形式返回结果<br />2、修改录制数据结构。  |
2010| 4.1.1.1 | 1、对接批量获取控件信息能力,缩短获取控件信息的耗时。        |
2011| 4.1.2.0 | 1、增加shell命令方式注入UI模拟操作。                         |
2012| 4.1.3.0 | 1、新增命令行功能,uitest dumuLayout -a ,dump信息中包含控件的背景色、字体颜色/大小信息。 |
2013| 4.1.4.0 | 1、dump信息中增加hint与description字段。<br />2、优化多指操作。<br />3、优化查找控件的效率。<br />4、uitest uiInput执行效率提升。 |
2014| 5.0.1.0 | 1、优化swipe操作。<br />2、inputText输入中文的实现方式改为设置剪贴板数据后,长按控件点击粘贴。 |
2015| 5.0.1.1 | 1、节点新增以下属性,背景色:backgroundColor,背景图片:backgroundImage,透明度:opacity,模糊度:blur,事件是否透传:hitTestBehavior 。 |
2016| 5.0.1.2 | 1、通过test Sa发布公共事件。<br />2、节点新增clip属性,判断其子节点是否进行切割。<br />3、过滤机制调整,节点只与其clip为true的父节点进行切换计算可见区域,可见区域宽/高小于等于0记为不可见。<br />4、调用inputText时,被输入字符串超过200个字符时,实现方式调整为设置剪贴板数据后,植入ctrl + v。 |
2017| 5.1.1.1 | 1、控件支持正则表达式方式进行查找 <br />2、获取控件属性中的提示文本信息。  <br />3、支持横向滑动查找操作。  <br />4、支持不指定坐标模拟输入文本的shell命令 hdc shell uitest uiInput text "xxxx"。  |
2018| 5.1.1.2 | uitest dumpLayout 能力增强<br /> -w:仅获取指定window id的应用窗口。<br/> -b :仅获取指定bundleName的应用窗口。<br/> -m :是否进行窗口合并。不使用该选项时默认进行窗口合并。 |
2019| 6.0.1.0 | 1、inputText支持追加输入和指定通过剪贴板粘贴输入。  <br/>2、开放鼠标原子事件。  <br/>3、新增模拟手表表冠旋转。  <br/>4、支持触控屏/鼠标注入长按操作和拖拽操作时指定长按时间。 |
2020
2021
2022## 白盒性能测试框架功能特性
2023
2024白盒性能测试框架PerfTest提供白盒性能测试能力,供开发者在测试场景使用,支持对指定代码段或指定场景的性能数据测试,支持自动化执行测试代码段,并采集耗时、CPU、内存、时延、帧率等性能数据。
2025
2026**使用者在测试脚本通过如下方式引入使用:**
2027
2028```typescript
2029import { PerfMetric, PerfTest, PerfTestStrategy, PerfMeasureResult } from '@kit.TestKit';
2030```
2031
2032### 接口说明
2033
2034`PerfTest`类作为白盒性能测试框架的入口,提供测试任务创建、测试代码段执行和数据采集、测量结果获取等能力。支持通过`PerfTestStrategy`设置测试执行策略,执行测试,并通过`PerfMeasureResult`获取测量结果。
2035
2036| No.  | API                                                       | 功能描述               |
2037| ---- |-----------------------------------------------------------| ---------------------- |
2038| 1    | static create(strategy: PerfTestStrategy): PerfTest       | 静态方法,构造一个PerfTest对象,并返回该对象。 |
2039| 2    | run(): Promise\<void>                                     | 运行性能测试,迭代执行测试代码段并采集性能数据,使用Promise回调。         |
2040| 3    | getMeasureResult(metric: PerfMetric): PerfMeasureResult   | 获取指定性能指标的测量数据。           |
2041| 4    | destroy(): void                                           | 销毁PerfTest对象。      |
2042
2043`PerfTestStrategy`支持设置性能测试的执行策略,如测试性能指标、被测应用包名、迭代次数等。
2044
2045| 名称 | 类型   | 只读 |  可选 | 说明        |
2046| ---- | ------ | ---- | ---- |-----------|
2047| metrics     | Array\<[PerfMetric](#perfmetric)>           | 否 | 否 | 被测性能指标列表。  |
2048| actionCode  | Callback\<Callback\<boolean>> | 否 | 否 | 测试代码段。  |
2049| resetCode   | Callback\<Callback\<boolean>> | 否 | 是 | 测试结束环境重置代码段。默认为空,框架运行时不执行此代码段。  |
2050| bundleName  | string                      | 否 | 是 | 被测应用包名。默认为"",框架运行时测试当前测试应用的性能数据。  |
2051| iterations  | number                      | 否 | 是 | 测试迭代执行次数,默认值为5。  |
2052| timeout     | number                      | 否 | 是 | 单次代码段(actionCode/resetCode)执行的超时时间,默认值为10000ms。  |
2053
2054`PerfMeasureResult`用于获取每轮测试的数据以及最大值、最小值、平均值等统计数据。
2055
2056| 名称   | 类型   | 只读 | 可选 | 说明                      |
2057| ------ | ------ | ---- | ---- | ------------------------- |
2058| metric        | [PerfMetric](#perfmetric)    | 是 | 否 | 被测性能指标。  |
2059| roundValues   | Array\<number> | 是 | 否 | 被测性能指标的各轮测量数据值。当数据采集失败时返回-1。  |
2060| maximum       | number        | 是 | 否 | 各轮测量数据最大值(剔除为-1的数据后计算)。  |
2061| minimum       | number        | 是 | 否 | 各轮测量数据最小值(剔除为-1的数据后计算)。  |
2062| average       | number        | 是 | 否 | 各轮测量数据平均值(剔除为-1的数据后计算)。  |
2063
2064### 使用示例
2065
2066白盒性能测试框架PerfTest支持基于代码段和针对指定场景的性能测试,使用示例如下。
2067
2068**示例1:基于代码段的性能测试,测试函数执行期间的应用性能**
2069
2070- 在main > ets > utils文件夹下新增PerfUtils.ets文件,在文件中编写自定义的函数。
2071
2072  ```ts
2073  export class PerfUtils {
2074    public static CalculateTest() {
2075      let num: number = 0
2076      for (let index = 0; index < 10000; index++) {
2077        num++;
2078      }
2079    }
2080  }
2081  ```
2082
2083- 在ohosTest > ets > test文件夹下.test.ets文件中编写具体测试代码。
2084
2085  ```ts
2086  import { describe, it, expect } from '@ohos/hypium';
2087  import { PerfMetric, PerfTest, PerfTestStrategy, PerfMeasureResult } from '@kit.TestKit';
2088  import { PerfUtils } from '../../../main/ets/utils/PerfUtils';
2089
2090  export default function PerfTestTest() {
2091    describe('PerfTestTest', () => {
2092      it('testExample0', 0, async (done: Function) => {
2093        let metrics: Array<PerfMetric> = [PerfMetric.DURATION, PerfMetric.CPU_USAGE] // 指定被测指标
2094        let actionCode = async (finish: Callback<boolean>) => { // 测试代码段中使用uitest进行列表滑动
2095          await await PerfUtils.CalculateTest()
2096          finish(true);
2097        };
2098        let perfTestStrategy: PerfTestStrategy = {  // 定义测试策略
2099          metrics: metrics,
2100          actionCode: actionCode,
2101        };
2102        try {
2103          let perfTest: PerfTest = PerfTest.create(perfTestStrategy); // 创建测试任务对象PerfTest
2104          await perfTest.run(); // 执行测试,异步函数需使用await同步等待完成
2105          let res1: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.DURATION); // 获取耗时指标的测试结果
2106          let res2: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.CPU_USAGE); // 获取CPU使用率指标的测试结果
2107          perfTest.destroy(); // 销毁PerfTest对象
2108          expect(res1.average).assertLessOrEqual(1000); // 断言性能测试结果
2109          expect(res2.average).assertLessOrEqual(30); // 断言性能测试结果
2110        } catch (error) {
2111          console.error(`Failed to execute perftest. Cause:${JSON.stringify(error)}`);
2112          expect(false).assertTrue()
2113        }
2114        done();
2115      })
2116    })
2117  }
2118  ```
2119
2120**示例1:针对指定场景的性能测试,测试当前应用内列表滑动帧率**
2121
2122- 编写Index.ets页面代码,作为被测示例demo。
2123
2124  ```ts
2125  @Entry
2126  @Component
2127  struct ListPage {
2128    scroller: Scroller = new Scroller()
2129    private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2130    build() {
2131      Row() {
2132        Column() {
2133          Scroll(this.scroller) {
2134            Column() {
2135              ForEach(this.arr, (item: number) => {
2136                Text(item.toString())
2137                  .width('90%')
2138                  .height('40%')
2139                  .fontSize(80)
2140                  .textAlign(TextAlign.Center)
2141                  .margin({ top: 10 })
2142              }, (item: string) => item)
2143            }
2144          }
2145          .width('100%')
2146          .height('100%')
2147          .scrollable(ScrollDirection.Vertical)
2148          .scrollBar(BarState.On)
2149          .scrollBarColor(Color.Gray)
2150        }
2151        .width('100%')
2152      }
2153      .height('100%')
2154    }
2155  }
2156  ```
2157
2158- 在ohosTest > ets > test文件夹下.test.ets文件中编写具体测试代码。
2159
2160  ```ts
2161  import { describe, it, expect } from '@ohos/hypium';
2162  import { PerfMetric, PerfTest, PerfTestStrategy, PerfMeasureResult } from '@kit.TestKit';
2163  import { abilityDelegatorRegistry, Driver, ON } from '@kit.TestKit';
2164  import { Want } from '@kit.AbilityKit';
2165
2166  const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator();
2167  export default function PerfTestTest() {
2168    describe('PerfTestTest', () => {
2169      it('testExample',0, async (done: Function) => {
2170        let driver = Driver.create();
2171        await driver.delayMs(1000);
2172        const bundleName = abilityDelegatorRegistry.getArguments().bundleName;
2173        const want: Want = {
2174          bundleName: bundleName,
2175          abilityName: 'EntryAbility'
2176        };
2177        await delegator.startAbility(want); // 打开测试页面
2178        await driver.delayMs(1000);
2179        let scroll = await driver.findComponent(ON.type('Scroll'));
2180        await driver.delayMs(1000);
2181        let center = await scroll.getBoundsCenter();  // 获取Scroll可滚动组件坐标
2182        await driver.delayMs(1000);
2183        let metrics: Array<PerfMetric> = [PerfMetric.LIST_SWIPE_FPS]  // 指定被测指标为列表滑动帧率
2184        let actionCode = async (finish: Callback<boolean>) => { // 测试代码段中使用uitest进行列表滑动
2185          await driver.fling({x: center.x, y: Math.floor(center.y * 3 / 2)}, {x: center.x, y: Math.floor(center.y / 2)}, 50, 20000);
2186          await driver.delayMs(3000);
2187          finish(true);
2188        };
2189        let resetCode = async (finish: Callback<boolean>) => {  // 复位环境,将列表划至顶部
2190          await scroll.scrollToTop(40000);
2191          await driver.delayMs(1000);
2192          finish(true);
2193        };
2194        let perfTestStrategy: PerfTestStrategy = {  // 定义测试策略
2195          metrics: metrics,
2196          actionCode: actionCode,
2197          resetCode: resetCode,
2198          iterations: 5,  // 指定测试迭代次数
2199          timeout: 50000, // 指定actionCode和resetCode的超时时间
2200        };
2201        try {
2202          let perfTest: PerfTest = PerfTest.create(perfTestStrategy); // 创建测试任务对象PerfTest
2203          await perfTest.run(); // 执行测试,异步函数需使用await同步等待完成
2204          let res: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.LIST_SWIPE_FPS); // 获取列表滑动帧率指标的测试结果
2205          perfTest.destroy(); // 销毁PerfTest对象
2206          expect(res.average).assertLargerOrEqual(60);  // 断言性能测试结果
2207        } catch (error) {
2208          console.error(`Failed to execute perftest. Cause:${JSON.stringify(error)}`);
2209        }
2210        done();
2211      })
2212    })
2213  }
2214  ```
2215
2216PerfTest完整的API列表请参考[API文档](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.test.PerfTest.d.ts)及[示例文档说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-test-kit/js-apis-perftest.md)