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