• 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,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