• Home
Name Date Size #Lines LOC

..--

acl/developtools_integration_verification/22-Oct-2025-

coverage_signal_handler/22-Oct-2025-7351

hamock/22-Oct-2025-1,4291,111

jsunit/22-Oct-2025-12,18010,430

perftest/22-Oct-2025-4,8343,784

testserver/22-Oct-2025-2,3061,761

uitest/22-Oct-2025-26,55922,569

CODEOWNERSD22-Oct-2025602 1413

LICENSED22-Oct-20259.9 KiB177150

OAT.xmlD22-Oct-20253.8 KiB6112

README_en.mdD22-Oct-202548.1 KiB1,110866

README_zh.mdD22-Oct-202597.3 KiB2,2161,854

arkxtest_config.gniD22-Oct-2025675 1816

bundle.jsonD22-Oct-20253 KiB103102

README_en.md

1# arkXtest
2
3## Introduction
4arkXtest, the automated test framework of OpenHarmony, consists of the JS unit test framework (JsUnit) and UI test framework (UiTest).
5
6JsUnit provides APIs for writing test cases for system or application interfaces, executing unit test cases, and generating test reports.
7
8UiTest provides simple and easy-to-use APIs for locating and operating UI components, helping users to develop automatic test scripts based on UI operations.
9
10## Directory Structure
11
12```
13arkXtest
14  |-----jsunit  Unit test framework
15  |-----uitest UI test framework
16```
17## Constraints
18The initial APIs of this module are supported since API version 8. Newly added APIs will be marked with a superscript to indicate their earliest API version.
19
20## JsUnit Features
21
22| No.  | Feature    | Description                                                    |
23| ---- | -------- | ------------------------------------------------------------ |
24| 1    | Basic process support| Provides APIs for writing and executing test cases.                                    |
25| 2    | Assertion library  | Provides APIs for checking whether the actual value of a test case is the same as the expected value.                        |
26| 3    | Mock| Provides APIs for mocking functions to return the specified value or perform the specified action.|
27| 4    | Data driving| Provides APIs for reusing a test script with different input data.|
28
29### How to Use
30
31####  Basic Process Support
32
33Test cases use the common syntax in the industry. **describe** defines a test suite, and **it** specifies a test case.
34
35| No.  | API        | Description                                                    |
36| ---- | ---------- | ------------------------------------------------------------ |
37| 1    | describe   | Defines a test suite. This API supports two parameters: test suite name and test suite function.      |
38| 2    | beforeAll  | Presets an action, which is performed only once before all test cases of the test suite start. This API supports only one parameter: preset action function.|
39| 3    | beforeEach | Presets an action, which is performed before each unit test case starts. The number of execution times is the same as the number of test cases defined by **it**. This API supports only one parameter: preset action function.|
40| 4    | afterEach  | Presets a clear action, which is performed after each unit test case ends. The number of execution times is the same as the number of test cases defined by **it**. This API supports only one parameter: clear action function.|
41| 5    | afterAll   | Presets a clear action, which is performed after all test cases of the test suite end. This API supports only one parameter: clear action function.|
42| 6    | it         | Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.|
43| 7    | expect     | Defines a variety of assertion methods, which are used to declare expected Boolean conditions.                            |
44
45The sample code is as follows:
46
47```javascript
48import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
49import demo from '@ohos.bundle'
50
51export default async function abilityTest() {
52  describe('ActsAbilityTest', function () {
53    it('String_assertContain_success', 0, function () {
54      let a = 'abc'
55      let b = 'b'
56      expect(a).assertContain(b)
57      expect(a).assertEqual(a)
58    })
59    it('getBundleInfo_0100', 0, async function () {
60      const NAME1 = "com.example.MyApplicationStage"
61      await demo.getBundleInfo(NAME1,
62        demo.BundleFlag.GET_BUNDLE_WITH_ABILITIES | demo.BundleFlag.GET_BUNDLE_WITH_REQUESTED_PERMISSION)
63        .then((value) => {
64          console.info(value.appId)
65        })
66        .catch((err) => {
67          console.info(err.code)
68        })
69    })
70  })
71}
72```
73
74
75
76####  Assertion Library
77
78Available APIs:
79
80
81| No.  | API              | Description                                                  |
82| :--- | :--------------- | ------------------------------------------------------------ |
83| 1    | assertClose      | Checks whether the proximity between the actual value and the expected value (0) is the expected value (1). |
84| 2    | assertContain    | Checks whether the actual value contains the expected value. |
85| 3    | assertEqual      | Checks whether the actual value is equal to the expected value. |
86| 4    | assertFail       | Throws an error.                                             |
87| 5    | assertFalse      | Check whether the actual value is **false**.                 |
88| 6    | assertTrue       | Checks whether the actual value is **true**.                 |
89| 7    | assertInstanceOf | Checks whether the actual value is of the type specified by the expected value,basic types are supported. |
90| 8    | assertLarger     | Checks whether the actual value is greater than the expected value. |
91| 9    | assertLess       | Checks whether the actual value is less than the expected value. |
92| 10   | assertNull       | Checks whether the actual value is null.                     |
93| 11   | assertThrowError | Checks whether the error thrown by the actual value is the expected value. |
94| 12   | assertUndefined  | Checks whether the actual value is **undefined**.            |
95
96The sample code is as follows:
97
98```javascript
99import { describe, it, expect } from '@ohos/hypium'
100export default async function abilityTest() {
101  describe('assertClose', function () {
102    it('assertBeClose_success', 0, function () {
103      let a = 100
104      let b = 0.1
105      expect(a).assertClose(99, b)
106    })
107    it('assertBeClose_fail', 0, function () {
108      let a = 100
109      let b = 0.1
110      expect(a).assertClose(1, b)
111    })
112    it('assertBeClose_fail', 0, function () {
113      let a = 100
114      let b = 0.1
115      expect(a).assertClose(null, b)
116    })
117    it('assertBeClose_fail', 0, function () {
118      expect(null).assertClose(null, 0)
119    })
120    it('assertInstanceOf_success', 0, function () {
121      let a = 'strTest'
122      expect(a).assertInstanceOf('String')
123    })
124  })
125}
126```
127
128
129#### Mock
130
131##### Constraints
132
133JsUnit provides the mock capability since npm [1.0.1](https://repo.harmonyos.com/#/en/application/atomService/@ohos%2Fhypium). You must modify the npm version in **package.info** of the source code project before using the mock capability.
134
135-  **Available APIs**
136
137| No. | API | Description|
138| --- | --- | --- |
139| 1 | mockFunc(obj: object, f: function())| Mocks a function in the object of a class. The parameters **obj** and **f** must be passed in. This API supports asynchronous functions. <br>**NOTE**: This API does not focus on the implementation of the original function. Therefore, it does not matter whether the original function is implemented synchronously or asynchronously.|
140| 2 | when(mockedfunc: function)| Checks whether the input function is mocked and marked. A function declaration is returned.|
141| 3 | afterReturn(x: value)| Sets an expected return value, for example, a string or promise.|
142| 4 | afterReturnNothing() | Sets the expected return value to **undefined**, that is, no value will be returned.|
143| 5 | afterAction(x: action)| Sets the expected return value to be an action executed by a function.|
144| 6 | afterThrow(x: msg)| Sets an exception to throw and the error message.|
145| 7 | clear() | Restores the mocked object after the test case is complete (restores the original features of the object).|
146| 8 | any | Returns the expected value if a parameter of any type (except **undefined** and **null**) is passed in. This API must be called by **ArgumentMatchers.any**.|
147| 9 | anyString | Returns the expected value if a string is passed in. This API must be called by **ArgumentMatchers.anyString**.|
148| 10 | anyBoolean | Returns the expected value if a Boolean value is passed in. This API must be called by **ArgumentMatchers.anyBoolean**.|
149| 11 | anyFunction | Returns the expected value if a function is passed in. This API must be called by **ArgumentMatchers.anyFunction**.|
150| 12 | anyNumber | Returns the expected value if a number is passed in. This API must be called by **ArgumentMatchers.anyNumber**.|
151| 13 | anyObj | Returns the expected value if an object is passed in. This API must be called by **ArgumentMatchers.anyObj**.|
152| 14 | matchRegexs(Regex) | Returns the expected value if a regular expression is passed in. This API must be called by **ArgumentMatchers.matchRegexs(Regex)**.|
153| 15 | verify(methodName, argsArray) | Verifies whether a function and its parameters are processed as expected. This API returns a **VerificationMode**, which is a class that provides the verification mode. This class provides functions such as **times(count)**, **once()**, **atLeast(x)**, **atMost(x)**, and **never()**.|
154| 16 | times(count) | Verifies whether the function was executed the specified number of times.|
155| 17 | once() | Verifies whether the function was executed only once.|
156| 18 | atLeast(count) | Verifies whether the function was executed at least **count** times.|
157| 19 | atMost(count) | Verifies whether the function was executed at most **count** times.|
158| 20 | never | Verifies whether the function has never been executed.|
159| 21 | ignoreMock(obj, method) | Restores the mocked function in the object. This API is valid for mocked functions.|
160| 22 | clearAll() | Clears all data and memory after the test cases are complete.|
161
162-  **Examples**
163
164You can refer to the following examples to import the mock module and write test cases.
165
166- **NOTICE**<br>
167You must import **MockKit** and **when**. You can import other assertion APIs based on the test cases.
168Example: `import {describe, expect, it, MockKit, when} from '@ohos/hypium'`
169
170Example 1: Use **afterReturn**.
171
172```javascript
173import {describe, expect, it, MockKit, when} from '@ohos/hypium';
174
175export default function ActsAbilityTest() {
176    describe('ActsAbilityTest', function () {
177        it('testMockfunc', 0, function () {
178            console.info("it1 begin");
179
180            // 1. Create a MockKit object.
181            let mocker = new MockKit();
182
183            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
184            class ClassName {
185                constructor() {
186                }
187
188                method_1(arg) {
189                    return '888888';
190                }
191
192                method_2(arg) {
193                    return '999999';
194                }
195            }
196
197            let claser = new ClassName();
198
199            // 3. Mock method_1 of the ClassName class.
200            let mockfunc = mocker.mockFunc(claser, claser.method_1);
201            when(mockfunc)('test').afterReturn('1');
202
203            // 4. Assert whether the mocked function is implemented as expected.
204            // The operation is successful if 'test' is passed in.
205            expect(claser.method_1('test')).assertEqual('1'); // The operation is successful.
206
207            // The operation fails if 'abc' is passed in.
208            //expect(claser.method_1('abc')).assertEqual('1'); // The operation fails.
209        });
210    });
211}
212```
213- **NOTICE**<br>
214In `when(mockfunc)('test').afterReturn('1');`, `('test')` is the value to pass in the mocked function. Currently, only one parameter is supported. `afterReturn('1')` is the expected return value. The expected value is returned only when `('test')` is passed in.
215
216Example 2: Use **afterReturnNothing**.
217
218```javascript
219import {describe, expect, it, MockKit, when} from '@ohos/hypium';
220
221export default function ActsAbilityTest() {
222    describe('ActsAbilityTest', function () {
223        it('testMockfunc', 0, function () {
224            console.info("it1 begin");
225
226            // 1. Create a MockKit object.
227            let mocker = new MockKit();
228
229            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
230            class ClassName {
231                constructor() {
232                }
233
234                method_1(arg) {
235                    return '888888';
236                }
237
238                method_2(arg) {
239                    return '999999';
240                }
241            }
242
243            let claser = new ClassName();
244
245            // 3. Mock method_1 of the ClassName class.
246            let mockfunc = mocker.mockFunc(claser, claser.method_1);
247
248            // 4. Set the action to be performed when the test case ends. For example, set it to afterReturnNothing(), which returns no value.
249            when(mockfunc)('test').afterReturnNothing();
250
251            // 5. Assert whether the mocked function is implemented as expected. Use the assertion APIs corresponding to Step 4.
252            // The operation is successful if 'test' is passed in.
253            // The mocked claser.method_1 does not return '888888'. Instead, afterReturnNothing() takes effect, that is, no value is returned.
254            expect(claser.method_1('test')).assertUndefined(); // The operation is successful.
255
256            // The operation fails if '123' is passed in.
257            // expect(method_1(123)).assertUndefined();// The operation fails.
258        });
259    });
260}
261```
262
263Example 3: Set the parameter type to **any**, that is, allow any parameter value except **undefine** and **null**.
264
265
266- **NOTICE**<br>
267The **ArgumentMatchers** class, for example, **ArgumentMatchers.any**, must be imported.
268
269```javascript
270import {describe, expect, it, MockKit, when, ArgumentMatchers} from '@ohos/hypium';
271
272export default function ActsAbilityTest() {
273    describe('ActsAbilityTest', function () {
274        it('testMockfunc', 0, function () {
275            console.info("it1 begin");
276
277            // 1. Create a MockKit object.
278            let mocker = new MockKit();
279
280            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
281            class ClassName {
282                constructor() {
283                }
284
285                method_1(arg) {
286                    return '888888';
287                }
288
289                method_2(arg) {
290                    return '999999';
291                }
292            }
293
294            let claser = new ClassName();
295
296            // 3. Mock method_1 of the ClassName class.
297            let mockfunc = mocker.mockFunc(claser, claser.method_1);
298            // Set the parameter matcher and expected return value as required.
299            when(mockfunc)(ArgumentMatchers.any).afterReturn('1');
300
301            // 4. Assert whether the mocked function is implemented as expected.
302            // The operation is successful if a string is passed in.
303            expect(claser.method_1('test')).assertEqual('1'); // The operation is successful.
304            // The operation is successful if a number (for example '123') is passed in.
305            expect(claser.method_1(123)).assertEqual('1'); // The operation is successful.
306            // The operation is successful if a Boolean value (for example 'true') is passed in.
307            expect(claser.method_1(true)).assertEqual('1');// The operation is successful.
308
309            // The operation fails if an empty value is passed in.
310            //expect(claser.method_1()).assertEqual('1');// The operation fails.
311        });
312    });
313}
314```
315
316Example 4: Set the parameter type to **anyString**.
317
318```javascript
319import {describe, expect, it, MockKit, when, ArgumentMatchers} from '@ohos/hypium';
320
321export default function ActsAbilityTest() {
322    describe('ActsAbilityTest', function () {
323        it('testMockfunc', 0, function () {
324            console.info("it1 begin");
325
326            // 1. Create a MockKit object.
327            let mocker = new MockKit();
328
329            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
330            class ClassName {
331                constructor() {
332                }
333
334                method_1(arg) {
335                    return '888888';
336                }
337
338                method_2(arg) {
339                    return '999999';
340                }
341            }
342
343            let claser = new ClassName();
344
345            // 3. Mock method_1 of the ClassName class.
346            let mockfunc = mocker.mockFunc(claser, claser.method_1);
347            // Set the following parameters as required.
348            when(mockfunc)(ArgumentMatchers.anyString).afterReturn('1');
349
350            // 4. Assert whether the mocked function is implemented as expected.
351            // The operation is successful if a string is passed in.
352            expect(claser.method_1('test')).assertEqual('1'); // The operation is successful.
353            expect(claser.method_1('abc')).assertEqual('1'); // The operation is successful.
354
355            // The operation fails if a number or a Boolean value is passed in.
356            //expect(claser.method_1(123)).assertEqual('1'); // The operation fails.
357            //expect(claser.method_1(true)).assertEqual('1'); // The operation fails.
358        });
359    });
360}
361```
362
363Example 5: Set the parameter type to **matchRegexs (Regex)**.
364```javascript
365import {describe, expect, it, MockKit, when, ArgumentMatchers} from '@ohos/hypium';
366
367export default function ActsAbilityTest() {
368    describe('ActsAbilityTest', function () {
369        it('testMockfunc', 0, function () {
370            console.info("it1 begin");
371
372            // 1. Create a MockKit object.
373            let mocker = new MockKit();
374
375            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
376            class ClassName {
377                constructor() {
378                }
379
380                method_1(arg) {
381                    return '888888';
382                }
383
384                method_2(arg) {
385                    return '999999';
386                }
387            }
388
389            let claser = new ClassName();
390
391            // 3. Mock method_1 of the ClassName class.
392            let mockfunc = mocker.mockFunc(claser, claser.method_1);
393            // Set a regular expression to match, for example, /123456/.
394            when(mockfunc)(ArgumentMatchers.matchRegexs(/123456/)).afterReturn('1');
395
396            // 4. Assert whether the mocked function is implemented as expected.
397            // The operation is successful if a string, for example, '1234567898', is passed in.
398            expect(claser.method_1('1234567898')).assertEqual('1'); // The operation is successful.
399            // The string '1234567898' matches the regular expression /123456/.
400
401            // The operation fails if '1234' is passed in.
402            //expect(claser.method_1('1234').assertEqual('1'); // The operation fails because '1234' does not match the regular expression /123456/.
403        });
404    });
405}
406```
407
408Example 6: Use **verify()**.
409```javascript
410import {describe, expect, it, MockKit, when} from '@ohos/hypium';
411
412export default function ActsAbilityTest() {
413    describe('ActsAbilityTest', function () {
414        it('testMockfunc', 0, function () {
415            console.info("it1 begin");
416
417            // 1. Create a MockKit object.
418            let mocker = new MockKit();
419
420            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
421            class ClassName {
422                constructor() {
423                }
424
425                method_1(...arg) {
426                    return '888888';
427                }
428
429                method_2(...arg) {
430                    return '999999';
431                }
432            }
433
434            let claser = new ClassName();
435
436            // 3. Mock method_1 and method_2 of the ClassName class.
437            mocker.mockFunc(claser, claser.method_1);
438            mocker.mockFunc(claser, claser.method_2);
439
440            // 4. Call the following methods.
441            claser.method_1('abc', 'ppp');
442            claser.method_1('abc');
443            claser.method_1('xyz');
444            claser.method_1();
445            claser.method_1('abc', 'xxx', 'yyy');
446            claser.method_1();
447            claser.method_2('111');
448            claser.method_2('111', '222');
449
450            //5. Verify the mocked functions.
451            mocker.verify('method_1', []).atLeast(3); // The result is "failed".
452            // Verify whether 'method_1' with an empty parameter list was executed at least three times.
453            // The result is "failed" because 'method_1' with an empty parameter list was executed only twice in Step 4.
454            //mocker.verify('method_2',['111']).once(); // The result is "success".
455            //mocker.verify('method_2',['111',,'222']).once(); // The result is "success".
456        });
457    });
458}
459```
460
461Example 7: Use **ignoreMock(obj, method)**.
462```javascript
463import {describe, expect, it, MockKit, when, ArgumentMatchers} from '@ohos/hypium';
464
465export default function ActsAbilityTest() {
466    describe('ActsAbilityTest', function () {
467        it('testMockfunc', 0, function () {
468            console.info("it1 begin");
469
470            // 1. Create a MockKit object.
471            let mocker = new MockKit();
472
473            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
474            class ClassName {
475                constructor() {
476                }
477
478                method_1(...arg) {
479                    return '888888';
480                }
481
482                method_2(...arg) {
483                    return '999999';
484                }
485            }
486
487            let claser = new ClassName();
488
489            // 3. Mock method_1 and method_2 of the ClassName class.
490            let func_1 = mocker.mockFunc(claser, claser.method_1);
491            let func_2 = mocker.mockFunc(claser, claser.method_2);
492
493            // 4. Modify the mocked functions.
494            when(func_1)(ArgumentMatchers.anyNumber).afterReturn('4');
495            when(func_2)(ArgumentMatchers.anyNumber).afterReturn('5');
496
497            // 5. Call the following methods.
498            console.log(claser.method_1(123)); // The return value is 4, which is the same as the expected value in Step 4.
499            console.log(claser.method_2(456)); // The return value is 5, which is the same as the expected value in Step 4.
500
501            // 6. Restore method_1 using ignoreMock().
502            mocker.ignoreMock(claser, claser.method_1);
503            // Call claser.method_1 and check the execution result.
504            console.log(claser.method_1(123)); // The return value is 888888, which is the same as that returned by the original function.
505            // Test with assertions.
506            expect(claser.method_1(123)).assertEqual('4'); // The return value is "failed", which meets the expected value of ignoreMock().
507            claser.method_2(456); // The return value is 5, which is the same as the expected value in Step 4 because method_2 is not restored.
508        });
509    });
510}
511```
512
513Example 8: Use **clear()**.
514
515```javascript
516import {describe, expect, it, MockKit, when, ArgumentMatchers} from '@ohos/hypium';
517
518export default function ActsAbilityTest() {
519    describe('ActsAbilityTest', function () {
520        it('testMockfunc', 0, function () {
521            console.info("it1 begin");
522
523            // 1. Create a MockKit object.
524            let mocker = new MockKit();
525
526            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
527            class ClassName {
528                constructor() {
529                }
530
531                method_1(...arg) {
532                    return '888888';
533                }
534
535                method_2(...arg) {
536                    return '999999';
537                }
538            }
539            let claser = new ClassName();
540
541            // 3. Mock method_1 and method_2 of the ClassName class.
542            let func_1 = mocker.mockFunc(claser, claser.method_1);
543            let func_2 = mocker.mockFunc(claser, claser.method_2);
544
545            // 4. Modify the mocked functions.
546            when(func_1)(ArgumentMatchers.anyNumber).afterReturn('4');
547            when(func_2)(ArgumentMatchers.anyNumber).afterReturn('5');
548
549            // 5. Call the following methods.
550            //expect(claser.method_1(123)).assertEqual('4'); // The return value is the same as the expected value.
551            //expect(claser.method_2(456)).assertEqual('5'); // The return value is the same as the expected value.
552
553            // 6. Clear the mock operation.
554            mocker.clear(claser);
555            // Call claser.method_1 and check the execution result.
556            expect(claser.method_1(123)).assertEqual('4'); // The return value is "failed", which meets the expectation.
557            expect(claser.method_2(456)).assertEqual('5'); // The return value is "failed", which meets the expectation.
558        });
559    });
560}
561```
562
563
564Example 9: Use **afterThrow(msg)**.
565
566```javascript
567import {describe, expect, it, MockKit, when} from '@ohos/hypium';
568
569export default function ActsAbilityTest() {
570    describe('ActsAbilityTest', function () {
571        it('testMockfunc', 0, function () {
572            console.info("it1 begin");
573
574            // 1. Create a MockKit object.
575            let mocker = new MockKit();
576
577            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
578            class ClassName {
579                constructor() {
580                }
581
582                method_1(arg) {
583                    return '888888';
584                }
585            }
586
587            let claser = new ClassName();
588
589            // 3. Mock method_1 of the ClassName class.
590            let mockfunc = mocker.mockFunc(claser, claser.method_1);
591
592            // 4. Set the action to be performed when the test case ends. For example, set it to afterReturnNothing(), which returns no value.
593            when(mockfunc)('test').afterThrow('error xxx');
594
595            // 5. Execute the mocked function, capture the exception, and use assertEqual() to check whether message meets the expectation.
596            try {
597                claser.method_1('test');
598            } catch (e) {
599                expect(e).assertEqual('error xxx'); // The execution is successful.
600            }
601        });
602    });
603}
604```
605
606Example 10: Mock asynchronous functions.
607
608```javascript
609import {describe, expect, it, MockKit, when} from '@ohos/hypium';
610
611export default function ActsAbilityTest() {
612    describe('ActsAbilityTest', function () {
613        it('testMockfunc', 0, function () {
614            console.info("it1 begin");
615
616            // 1. Create a MockKit object.
617            let mocker = new MockKit();
618
619            // 2. Define the ClassName class, which contains two functions, and then create a claser object.
620            class ClassName {
621                constructor() {
622                }
623
624                async method_1(arg) {
625                    return new Promise((res, rej) => {
626                        // Perform asynchronous operations.
627                        setTimeout(function () {
628                            console.log ('Execute');
629                            res('Pass data');
630                        }, 2000);
631                    });
632                }
633            }
634
635            let claser = new ClassName();
636
637            // 3. Mock method_1 of the ClassName class.
638            let mockfunc = mocker.mockFunc(claser, claser.method_1);
639
640            // 4. Set the action to be performed after the test case ends. For example, set it to afterRetrun(), which returns a custom promise.
641            when(mockfunc)('test').afterReturn(new Promise((res, rej) => {
642                console.log("do something");
643                res('success something');
644            }));
645
646            // 5. Execute the mocked function, that is, execute the promise.
647            claser.method_1('test').then(function (data) {
648                // Code for data processing
649                console.log('result : ' + data);
650            });
651        });
652    });
653}
654```
655
656Example 11: Mock a system function.
657
658```javascript
659export default function ActsAbilityTest() {
660    describe('ActsAbilityTest', function () {
661        it('test_systemApi', 0, function () {
662            // 1. Create a MockKit object.
663            let mocker = new MockKit();
664            // 2. Mock the app.getInfo() function.
665            let mockf = mocker.mockFunc(app, app.getInfo);
666            when(mockf)('test').afterReturn('1');
667            // The operation is successful.
668            expect(app.getInfo('test')).assertEqual('1');
669        });
670    });
671}
672```
673
674
675Example 12: Verify **times(count)**.
676
677```javascript
678import { describe, expect, it, MockKit, when } from '@ohos/hypium'
679
680export default function ActsAbilityTest() {
681    describe('ActsAbilityTest', function () {
682        it('test_verify_times', 0, function () {
683            // 1. Create a MockKit object.
684            let mocker = new MockKit();
685            // 2. Define the class to be mocked.
686            class ClassName {
687                constructor() {
688                }
689
690                method_1(...arg) {
691                    return '888888';
692                }
693            }
694            // 3. Create an object of the class.
695            let claser = new ClassName();
696            // 4. Mock a function, for example, method_1, of the object.
697            let func_1 = mocker.mockFunc(claser, claser.method_1);
698            // 5. Set the expected value to be returned by the mocked function.
699            when(func_1)('123').afterReturn('4');
700
701            // 6. Execute the function several times, with parameters set as follows:
702            claser.method_1('123', 'ppp');
703            claser.method_1('abc');
704            claser.method_1('xyz');
705            claser.method_1();
706            claser.method_1('abc', 'xxx', 'yyy');
707            claser.method_1('abc');
708            claser.method_1();
709            // 7. Check whether method_1 with the parameter of 'abc' was executed twice.
710            mocker.verify('method_1', ['abc']).times(2);
711        });
712    });
713}
714```
715
716
717Example 13: Verify **atLeast(count)**.
718
719```javascript
720import { describe, expect, it, MockKit, when } from '@ohos/hypium'
721
722export default function ActsAbilityTest() {
723    describe('ActsAbilityTest', function () {
724        it('test_verify_atLeast', 0, function () {
725            // 1. Create a MockKit object.
726            let mocker = new MockKit();
727            // 2. Define the class to be mocked.
728            class ClassName {
729                constructor() {
730                }
731
732                method_1(...arg) {
733                    return '888888';
734                }
735            }
736
737            // 3. Create an object of the class.
738            let claser = new ClassName();
739            // 4. Mock a function, for example, method_1, of the object.
740            let func_1 = mocker.mockFunc(claser, claser.method_1);
741            // 5. Set the expected value to be returned by the mocked function.
742            when(func_1)('123').afterReturn('4');
743            // 6. Execute the function several times, with parameters set as follows:
744            claser.method_1('123', 'ppp');
745            claser.method_1('abc');
746            claser.method_1('xyz');
747            claser.method_1();
748            claser.method_1('abc', 'xxx', 'yyy');
749            claser.method_1();
750            // 7. Check whether method_1 with an empty value was executed at least twice.
751            mocker.verify('method_1', []).atLeast(2);
752        });
753    });
754}
755```
756
757#### Data Driving
758
759##### Constraints
760
761JsUnit provides the following data driving capability since [Hypium 1.0.2](https://repo.harmonyos.com/#/en/application/atomService/@ohos%2Fhypium):
762
763- Passes parameters for the specified test suite and test case.
764- Specifies the number of times that the test suite and test case are executed.
765
766The execution times of test cases and the parameters passed in each time are determined by the settings in **data.json**. The file content is as follows:
767
768>**NOTE**<br>The **data.json** file is in the same directory as the **.test.js** or **.test.ets** file.
769
770```json
771{
772	"suites": [{
773		"describe": ["actsAbilityTest"],
774		"stress": 2,
775		"params": {
776			"suiteParams1": "suiteParams001",
777			"suiteParams2": "suiteParams002"
778		},
779		"items": [{
780			"it": "testDataDriverAsync",
781			"stress": 2,
782			"params": [{
783				"name": "tom",
784				"value": 5
785			}, {
786				"name": "jerry",
787				"value": 4
788			}]
789		}, {
790			"it": "testDataDriver",
791			"stress": 3
792		}]
793	}]
794}
795```
796
797Parameter description:
798
799|      | Name| Description                                 | Mandatory|
800| :--- | :--------- | :------------------------------------ | ---- |
801| 1    | "suite"    | Test suite configuration.                        | Yes  |
802| 2    | "items"    | Test case configuration.                      | Yes  |
803| 3    | "describe" | Test suite name.                        | Yes  |
804| 4    | "it"       | Test case name.                      | Yes  |
805| 5    | "params"   | Parameters to be passed to the test suite or test case.| No  |
806| 6    | "stress"   | Number of times that the test suite or test case is executed.    | No  |
807
808The sample code is as follows:
809
810Import the **data.json** file to the **app.js** or **app.ets** file in the **TestAbility** directory, and set parameters before executing the **Hypium.hypiumTest()** method.
811
812```javascript
813import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
814import { Hypium } from '@ohos/hypium'
815import testsuite from '../test/List.test'
816import data from '../test/data.json';
817
818...
819Hypium.setData(data);
820Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
821...
822```
823
824```javascript
825import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from '@ohos/hypium';
826
827export default function abilityTest() {
828    describe('actsAbilityTest', function () {
829        it('testDataDriverAsync', 0, async function (done, data) {
830            console.info('name: ' + data.name);
831            console.info('value: ' + data.value);
832            done();
833        });
834
835        it('testDataDriver', 0, function () {
836            console.info('stress test');
837        });
838    });
839}
840```
841
842### How to Use
843
844JsUnit is released as an npm (hypium) package at the [service component official website](https://repo.harmonyos.com/#/en/application/atomService/@ohos%2Fhypium). You can download Deveco Studio, configure dependencies in the application project, and use JsUnit. For details about how to create a test project and execute test scripts, see the [OpenHarmony Test Framework](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001267284568).
845
846## UiTest Features
847
848| No.  | Feature       | Description                                                    |
849| ---- | ----------- | ------------------------------------------------------------ |
850| 1    | UiDriver    | Provides the UI test entry. It provides APIs for locating a component, checking whether a component exists, and injecting a key.|
851| 2    | By          | Describes the attributes (such as text, ID, and type) of UI components. `UiDriver` locates the component based on the attributes described by `By`.|
852| 3    | UiComponent | Provides the UI component object, which provides APIs for obtaining component attributes, clicking a component, and scrolling to search for a component.|
853| 4    | UiWindow    | Provides the window object, which provides APIs for obtaining window attributes, dragging a window, and adjusting the window size.|
854
855Import the following to the test script:
856
857```typescript
858import {UiDriver,BY,UiComponent,Uiwindow,MatchPattern} from '@ohos.uitest'
859```
860
861> **NOTICE**<br>
862> - All APIs provided by the `By` class are synchronous. You can use `builder` to call the APIs in chain mode to construct component filtering conditions.
863> - All the APIs provided by the `UiDriver` and `UiComponent` classes are asynchronous (in `Promise` mode), and `await` must be used.
864> - All UI test cases must be written in the asynchronous syntax and comply with the asynchronous test case specifications of JsUnit.
865
866
867
868Import the `By`, `UiDriver`, and `UiComponent` classes to the test case file, and then call the APIs to write test cases.
869
870```javascript
871import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from '@ohos/hypium'
872import {BY, UiDriver, UiComponent, MatchPattern} from '@ohos.uitest'
873
874export default async function abilityTest() {
875  describe('uiTestDemo', function() {
876    it('uitest_demo0', 0, async function() {
877      // create UiDriver
878      let driver = await UiDriver.create()
879      // find component by text
880      let button = await driver.findComponent(BY.text('hello').enabled(true))
881      // click component
882      await button.click()
883      // get and assert component text
884      let content = await button.getText()
885      expect(content).assertEquals('clicked!')
886    })
887  })
888}
889```
890
891### Using UiDriver
892
893As the main entry to UiTest, the `UiDriver` class provides APIs for component matching/search, key injection, coordinate clicking/swiping, and screenshot.
894
895| No.  | API                                                          | Description                |
896| ---- | ------------------------------------------------------------ | ------------------------ |
897| 1    | create():Promise<UiDriver>                                   | Creates a **UiDriver** object. This API is a static method.|
898| 2    | findComponent(b:By):Promise<UiComponent>                     | Searches for a component.          |
899| 3    | pressBack():Promise<void>                                    | Presses the BACK button.            |
900| 4    | click(x:number, y:number):Promise<void>                      | Clicks a specific point based on the given coordinates.      |
901| 5    | swipe(x1:number, y1:number, x2:number, y2:number):Promise<void> | Swipes based on the given coordinates.      |
902| 6    | assertComponentExist(b:By):Promise<void>                     | Asserts that the component matching the given attributes exists on the current page.    |
903| 7    | delayMs(t:number):Promise<void>                              | Delays this **UiDriver** object for the specified duration.                  |
904| 8    | screenCap(s:path):Promise<void>                              | Captures the current screen.                  |
905| 9    | findWindow(filter: WindowFilter): Promise<UiWindow>          | Searches for a window.          |
906
907**assertComponentExist()** is an assertion API, which is used to assert that the target component exists on the current page. If the component does not exist, a JS exception will be thrown, causing the test case to fail.
908
909```javascript
910import {BY,UiDriver,UiComponent} from '@ohos.uitest'
911
912export default async function abilityTest() {
913  describe('UiTestDemo', function() {
914    it('Uitest_demo0', 0, async function(done) {
915      try{
916        // create UiDriver
917        let driver = await UiDriver.create()
918        // assert text 'hello' exists on current Ui
919        await assertComponentExist(BY.text('hello'))
920      } finally {
921        done()
922      }
923    })
924  })
925}
926```
927
928For details about the APIs of `UiDriver`, see [@ohos.uitest.d.ts](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts) and [UiDriver](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-uitest.md#uidriver).
929
930### Using By
931
932UiTest provides a wide range of UI component feature description APIs in the `By` class to filter and match components. The APIs provided by `By` exhibit the following features:
933
934- Allow one or more attributes as the match conditions. For example, you can specify both the text and id attributes to find a component.
935- Provide a variety of match patterns (`EQUALS`, `CONTAINS`, `STARTS_WITH`, and `ENDS_WITH`) for component attributes.
936- Support relative positioning for components. APIs such as `isBefore` and `isAfter` can be used to specify the features of adjacent components to assist positioning.
937
938| No.  | API                                | Description                                        |
939| ---- | ---------------------------------- | ------------------------------------------------ |
940| 1    | id(i:number):By                    | Specifies the component ID.                                    |
941| 2    | text(t:string, p?:MatchPattern):By | Specifies the component text. You can specify the match pattern.                  |
942| 3    | type(t:string)):By                 | Specifies the component type.                                  |
943| 4    | enabled(e:bool):By                 | Specifies the component state, which can be enabled or disabled.                              |
944| 5    | clickable(c:bool):By               | Specifies the clickable status of the component.                            |
945| 6    | focused(f:bool):By                 | Specifies the focused status of the component.                              |
946| 7    | scrollable(s:bool):By              | Specifies the scrollable status of the component.                            |
947| 8    | selected(s:bool):By                | Specifies the selected status of the component.                              |
948| 9    | isBefore(b:By):By                  | Specifies the attributes of the component that locates before the target component.|
949| 10   | isAfter(b:By):By                   | Specifies the attributes of the component that locates after the target component.|
950
951The `text` attribute supports match patterns `MatchPattern.EQUALS`, `MatchPattern.CONTAINS`, `MatchPattern.STARTS_WITH`, and `MatchPattern.ENDS_WITH`. The default match pattern is `MatchPattern.EQUALS`.
952
953For details about the APIs of `By`, see [@ohos.uitest.d.ts](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts) and [By](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-uitest.md#by).
954
955#### Absolute Positioning of a Component
956
957Example 1: Search for component `Id_button`.
958
959```javascript
960let button = await driver.findComponent(BY.id(Id_button))
961```
962
963 Example 2: Search for component `Id_button` in the `enabled` state. Use this API when the component cannot be located based on a single attribute.
964
965```javascript
966let button = await driver.findComponent(BY.id(Id_button).enabled(true))
967```
968
969Use `By.id(x).enabled(y)` to specify multiple attributes of the target component.
970
971Example 3: Search for the component whose text contains `hello`. Use this API when the component attribute values cannot be completely determined.
972
973```javascript
974let txt = await driver.findComponent(BY.text("hello", MatchPattern.CONTAINS))
975```
976
977`By.text()` passes the second parameter `MatchPattern.CONTAINS` to specify the matching rule. The default rule is `MatchPattern.EQUALS`, that is, the text attribute of the target component must be equal to the specified value.
978
979####  Relative Positioning of a Component
980
981Example 1: Search for the switch component `ResourceTable.Id_switch` following the text component `Item3_3`.
982
983```javascript
984let switch = await driver.findComponent(BY.id(Id_switch).isAfter(BY.text("Item3_3")))
985```
986
987Use `By.isAfter` to specify the attributes of the feature component located before the target component for relative positioning. Generally, a feature component is a component that has a globally unique feature (for example, a unique ID or a unique text).
988
989Similarly, you can use `By.isBefore` to specify the attributes of the feature component located after the target component to implement relative positioning.
990
991### Using UiComponent
992
993The `UiComponent` class represents a UI component, which can be located by using `UiDriver.findComponent(by)`. It provides APIs for obtaining component attributes, clicking a component, scrolling to search for a component, and text injection.
994
995`UiComponent` provides the following APIs:
996
997| No.  | API                               | Description                                      |
998| ---- | --------------------------------- | ---------------------------------------------- |
999| 1    | click():Promise<void>             | Clicks the component.                                  |
1000| 2    | inputText(t:string):Promise<void> | Inputs text into the component. This API is applicable to text box components.          |
1001| 3    | scrollSearch(s:By):Promise<bool>  | Scrolls on this component to search for the target component. This API is applicable to the **List** components.|
1002| 4    | getText():Promise<string>         | Obtains the component text.                                |
1003| 5    | getId():Promise<number>           | Obtains the component ID.                                  |
1004| 6    | getType():Promise<string>         | Obtains the component type.                                |
1005| 7    | isEnabled():Promise<bool>         | Obtains the component state, which can be enabled or disabled.                            |
1006
1007For details about the APIs of `UiComponent`, see [@ohos.uitest.d.ts](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts) and [UiComponent](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-uitest.md#uicomponent).
1008
1009Example 1: Click a component.
1010
1011```javascript
1012let button = await driver.findComponent(BY.id(Id_button))
1013await button.click()
1014```
1015
1016Example 2: After obtaining component attributes, use **assert()** to make assertion.
1017
1018```javascript
1019let component = await driver.findComponent(BY.id(Id_title))
1020expect(component !== null).assertTrue()
1021```
1022
1023Example 3: Scroll on the **List** component to locate the child component with text `Item3_3`.
1024
1025```javascript
1026let list = await driver.findComponent(BY.id(Id_list))
1027let found = await list.scrollSearch(BY.text("Item3_3"))
1028expect(found).assertTrue()
1029```
1030
1031Example 4: Input text in a text box.
1032
1033```javascript
1034let editText = await driver.findComponent(BY.type('InputText'))
1035await editText.inputText("user_name")
1036```
1037### Using UiWindow
1038
1039The `UiWindow` class represents a UI window, which can be located by using `UiDriver.findWindow(by)`. You can use the instance provided by this class to obtain window attributes, drag a window, and adjust the window size.
1040
1041`UiWindow` provides the following APIs:
1042
1043| No.  | API                                                          | Description                                          |
1044| ---- | ------------------------------------------------------------ | -------------------------------------------------- |
1045| 1    | getBundleName(): Promise<string>                             | Obtains the bundle name of the window.                            |
1046| 2    | getTitle(): Promise<string>                                  | Obtains the window title.                                |
1047| 3    | focus(): Promise<bool>                                       | Gives focus to the current window.                            |
1048| 4    | moveTo(x: number, y: number): Promise<bool>;                 | Moves the current window to the specified position. This API is applicable to the windows that can be moved.|
1049| 5    | resize(wide: number, height: number, direction: ResizeDirection): Promise<bool> | Adjusts the window size. This API is applicable to the windows that can be resized.        |
1050| 6    | split(): Promise<bool>                                       | Splits the current window. This API is applicable to the windows that support split-screen mode.  |
1051| 7    | close(): Promise<bool>                                       | Closes the current window.                                    |
1052
1053For details about the APIs of `UiWindow`, see [@ohos.uitest.d.ts](https://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.UiTest.d.ts) and [UiWindow](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-uitest.md#uiwindow9).
1054
1055Example 1: Obtain the window attributes.
1056
1057```javascript
1058let window = await driver.findWindow({actived: true})
1059let bundelName = await window.getBundleName()
1060```
1061
1062Example 2: Move the window.
1063
1064```javascript
1065let window = await driver.findWindow({actived: true})
1066await window.moveTo(500,500)
1067```
1068
1069Example 3: Close the window.
1070
1071```javascript
1072let window = await driver.findWindow({actived: true})
1073await window.close()
1074```
1075
1076### How to Use
1077
1078  Download Deveco Studio, create a test project, and call the APIs provided by UiTest to perform related tests. For details about how to create a test project and execute test scripts, see [OpenHarmony Test Framework](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001267284568).
1079  Run the following command to enable UiTest:
1080
1081>```shell
1082> hdc_std shell param set persist.ace.testmode.enabled 1
1083>```
1084### Building UiTest
1085
1086> UiTest is not built with OpenHarmony 3.1 Release and needs to be manually built.
1087
1088If you want to modify UiTest code and verify the modification, use the following commands.
1089
1090#### Building UiTest
1091
1092```shell
1093./build.sh --product-name rk3568 --build-target uitestkit
1094```
1095#### Sending UiTest
1096
1097```shell
1098hdc_std target mount
1099hdc_std shell mount -o rw,remount /
1100hdc_std file send uitest /system/bin/uitest
1101hdc_std file send libuitest.z.so /system/lib/module/libuitest.z.so
1102hdc_std shell chmod +x /system/bin/uitest
1103```
1104
1105### Version Information
1106
1107| Version | Description                                                  |
1108| :------ | :----------------------------------------------------------- |
1109| 3.2.2.1 | 1. Added the APIs for obtaining and setting the screen orientation and flinging.<br>2. Added the window processing logic for unsupported scenarios. |
1110

README_zh.md

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)