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