• Home
Name Date Size #Lines LOC

..--

jsunit/12-May-2024-2,2961,728

uitest/12-May-2024-8,6546,637

LICENSED12-May-20249.9 KiB177150

OAT.xmlD12-May-20243.8 KiB6112

README_zh.mdD12-May-202415.8 KiB354271

bundle.jsonD12-May-20241.2 KiB5857

README_zh.md

1# OpenHarmony自动化测试框架使用介绍
2
3## 简介
4 OpenHarmony自动化测试框架代码部件仓arkXtest,包含单元测试框架(JsUnit)和Ui测试框架(UiTest)。
5
6 单元测试框架(JsUnit)提供单元测试用例执行能力,提供用例编写基础接口,生成对应报告,用于测试系统或应用接口。
7
8 Ui测试框架(UiTest)通过简洁易用的API提供查找和操作界面控件能力,支持用户开发基于界面操作的自动化测试脚本。
9
10## 目录
11
12```
13arkXtest
14  |-----jsunit  单元测试框架
15  |-----uitest  Ui测试框架
16```
17## 约束限制
18本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
19
20## 单元测试框架功能特性
21
22| No.  | 特性     | 功能说明                           |
23| ---- | -------- | ---------------------------------- |
24| 1    | 基础流程 | 支持编写及执行基础用例             |
25| 2    | 断言库   | 判断用例实际期望值与预期值是否相符 |
26
27### 使用说明
28
29####  基础流程
30
31测试用例采用业内通用语法,describe代表一个测试套, it代表一条用例。
32
33| No.  | API        | 功能说明                                                     |
34| ---- | ---------- | ------------------------------------------------------------ |
35| 1    | describe   | 定义一个测试套,支持两个参数:测试套名称和测试套函数         |
36| 2    | beforeAll  | 在测试套内定义一个预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数 |
37| 3    | beforeEach | 在测试套内定义一个单元预置条件,在每条测试用例开始前执行,执行次数与it定义的测试用例数一致,支持一个参数:预置动作函数 |
38| 4    | afterEach  | 在测试套内定义一个单元清理条件,在每条测试用例结束后执行,执行次数与it定义的测试用例数一致,支持一个参数:清理动作函数 |
39| 5    | afterAll   | 在测试套内定义一个清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数 |
40| 6    | it         | 定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数 |
41| 7    | expect     | 支持bool类型判断等多种断言方法                               |
42
43示例代码:
44
45```javascript
46import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from 'hypium/index'
47import demo from '@ohos.bundle'
48
49export default async function abilityTest() {
50  describe('ActsAbilityTest', function () {
51    it('String_assertContain_success', 0, function () {
52      let a = 'abc'
53      let b = 'b'
54      expect(a).assertContain(b)
55      expect(a).assertEqual(a)
56    })
57    it('getBundleInfo_0100', 0, async function () {
58      const NAME1 = "com.example.MyApplicationStage"
59      await demo.getBundleInfo(NAME1,
60        demo.BundleFlag.GET_BUNDLE_WITH_ABILITIES | demo.BundleFlag.GET_BUNDLE_WITH_REQUESTED_PERMISSION)
61        .then((value) => {
62          console.info(value.appId)
63        })
64        .catch((err) => {
65          console.info(err.code)
66        })
67    })
68  })
69}
70```
71
72
73
74####  断言库
75
76断言功能列表:
77
78
79| No.  | API              | 功能说明                                                     |
80| :--- | :--------------- | ------------------------------------------------------------ |
81| 1    | assertClose      | 检验actualvalue和expectvalue(0)的接近程度是否是expectValue(1) |
82| 2    | assertContain    | 检验actualvalue中是否包含expectvalue                         |
83| 3    | assertEqual      | 检验actualvalue是否等于expectvalue[0]                        |
84| 4    | assertFail       | 抛出一个错误                                                 |
85| 5    | assertFalse      | 检验actualvalue是否是false                                   |
86| 6    | assertTrue       | 检验actualvalue是否是true                                    |
87| 7    | assertInstanceOf | 检验actualvalue是否是expectvalue类型                         |
88| 8    | assertLarger     | 检验actualvalue是否大于expectvalue                           |
89| 9    | assertLess       | 检验actualvalue是否小于expectvalue                           |
90| 10   | assertNull       | 检验actualvalue是否是null                                    |
91| 11   | assertThrowError | 检验actualvalue抛出Error内容是否是expectValue                |
92| 12   | assertUndefined  | 检验actualvalue是否是undefined                               |
93
94示例代码:
95
96```javascript
97import { describe, it, expect } from 'hypium/index'
98export default async function abilityTest() {
99  describe('assertClose', function () {
100    it('assertBeClose success', 0, function () {
101      let a = 100
102      let b = 0.1
103      expect(a).assertClose(99, b)
104    })
105    it('assertBeClose fail', 0, function () {
106      let a = 100
107      let b = 0.1
108      expect(a).assertClose(1, b)
109    })
110    it('assertBeClose fail', 0, function () {
111      let a = 100
112      let b = 0.1
113      expect(a).assertClose(null, b)
114    })
115    it('assertBeClose fail', 0, function () {
116      expect(null).assertClose(null, 0)
117    })
118  })
119}
120```
121### 使用方式
122
123  单元测试框架以npm包(hypium)形式发布至官网([https://www.npmjs.com/](https://www.npmjs.com/)),集成至sdk,开发者可以下载Deveco Studio使用,测试工程创建及测试脚本执行使用指南请参见[IDE指导文档](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453)124
125## Ui测试框架功能特性
126
127| No.  | 特性        | 功能说明                                                     |
128| ---- | ----------- | ------------------------------------------------------------ |
129| 1    | UiDriver    | Ui测试的入口,提供查找控件,检查控件存在性以及注入按键能力   |
130| 2    | By          | 用于描述目标控件特征(文本、id、类型等),`UiDriver`根据`By`描述的控件特征信息来查找控件 |
131| 3    | UiComponent | UiDriver查找返回的控件对象,提供查询控件属性,滑动查找等触控和检视能力 |
132
133**使用者在测试脚本通过如下方式引入使用:**
134
135```typescript
136import {UiDriver,BY,UiComponent,MatchPattern} from '@ohos.uitest'
137```
138
139> 注意事项
140> 1. `By`类提供的接口全部是同步接口,使用者可以使用`builder`模式链式调用其接口构造控件筛选条件。
141> 2. `UiDrivier`和`UiComponent`类提供的接口全部是异步接口(`Promise`形式),**需使用`await`语法**。
142> 3. Ui测试用例均需使用**异步**语法编写用例,需遵循单元测试框架异步用例编写规范。
143
144
145
146在测试用例文件中import `By/UiDriver/UiComponent`类,然后调用API接口编写测试用例。
147
148```javascript
149import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'hypium/index'
150import {BY, UiDriver, UiComponent, MatchPattern} from '@ohos.uitest'
151
152export default async function abilityTest() {
153  describe('uiTestDemo', function() {
154    it('uitest_demo0', 0, async function() {
155      // create UiDriver
156      let driver = await UiDriver.create()
157      // find component by text
158      let button = await driver.findComponent(BY.text('hello').enabled(true))
159      // click component
160      await button.click()
161      // get and assert component text
162      let content = await button.getText()
163      expect(content).assertEquals('clicked!')
164    })
165  })
166}
167```
168
169### UiDriver使用说明
170
171`UiDriver`类作为UiTest测试框架的总入口,提供查找控件,注入按键,单击坐标,滑动控件,手势操作,截图等能力。
172
173| No.  | API                                                          | 功能描述               |
174| ---- | ------------------------------------------------------------ | ---------------------- |
175| 1    | create():Promise<UiDriver>                                   | 静态方法,构造UiDriver |
176| 2    | findComponent(b:By):Promise<UiComponent>                     | 查找匹配控件           |
177| 3    | pressBack():Promise<void>                                    | 单击BACK键             |
178| 4    | click(x:number, y:number):Promise<void>                      | 基于坐标点的单击       |
179| 5    | swipe(x1:number, y1:number, x2:number, y2:number):Promise<void> | 基于坐标点的滑动       |
180| 6    | assertComponentExist(b:By):Promise<void>                     | 断言匹配的控件存在     |
181| 7    | delayMs(t:number):Promise<void>                              | 延时                   |
182| 8    | screenCap(s:path):Promise<void>                              | 截屏                   |
183
184其中assertComponentExist接口是断言API,用于断言当前界面存在目标控件;如果控件不存在,该API将抛出JS异常,使当前测试用例失败。
185
186```javascript
187import {BY,UiDriver,UiComponent} from '@ohos.uitest'
188
189export default async function abilityTest() {
190  describe('UiTestDemo', function() {
191    it('Uitest_demo0', 0, async function(done) {
192      try{
193        // create UiDriver
194        let driver = await UiDriver.create()
195        // assert text 'hello' exists on current Ui
196        await assertComponentExist(BY.text('hello'))
197      } finally {
198        done()
199      }
200    })
201  })
202}
203```
204
205### By使用说明
206
207Ui测试框架通过`By`类提供了丰富的控件特征描述API,用来匹配查找要操作或检视的目标控件。`By`提供的API能力具有以下特点:
208
209- 支持匹配单属性和匹配多属性组合,例如同时指定目标控件text和id。
210- 控件属性支持多种匹配模式(等于,包含,`STARTS_WITH`,`ENDS_WITH`)。
211- 支持相对定位控件,可通过`isBefore`和`isAfter`等API限定邻近控件特征进行辅助定位。
212
213| No.  | API                                | 功能描述                                       |
214| ---- | ---------------------------------- | ---------------------------------------------- |
215| 1    | id(i:number):By                    | 指定控件id                                     |
216| 2    | text(t:string, p?:MatchPattern):By | 指定控件文本,可指定匹配模式                   |
217| 3    | type(t:string)):By                 | 指定控件类型                                   |
218| 4    | enabled(e:bool):By                 | 指定控件使能状态                               |
219| 5    | clickable(c:bool):By               | 指定控件可单击状态                             |
220| 6    | focused(f:bool):By                 | 指定控件获焦状态                               |
221| 7    | scrollable(s:bool):By              | 指定控件可滑动状态                             |
222| 8    | selected(s:bool):By                | 指定控件选中状态                               |
223| 9    | isBefore(b:By):By                  | **相对定位**,限定目标控件位于指定特征控件之前 |
224| 10   | isAfter(b:By):By                   | **相对定位**,限定目标控件位于指定特征控件之后 |
225
226其中,`text`属性支持{`MatchPattern.EQUALS`,`MatchPattern.CONTAINS`,`MatchPattern.STARTS_WITH`,`MatchPattern.ENDS_WITH`}四种匹配模式,缺省使用`MatchPattern.EQUALS`模式。
227
228#### 控件绝对定位
229
230**示例代码1**:查找id是`Id_button`的控件。
231
232```javascript
233let button = await driver.findComponent(BY.id(Id_button))
234```
235
236 **示例代码2**:查找id是`Id_button`并且状态是`enabled`的控件,适用于无法通过单一属性定位的场景。
237
238```javascript
239let button = await driver.findComponent(BY.id(Id_button).enabled(true))
240```
241
242通过`By.id(x).enabled(y)`来指定目标控件的多个属性。
243
244**示例代码3**:查找文本中包含`hello`的控件,适用于不能完全确定控件属性取值的场景。
245
246```javascript
247let txt = await driver.findComponent(BY.text("hello", MatchPattern.CONTAINS))
248```
249
250通过向`By.text()`方法传入第二个参数`MatchPattern.CONTAINS`来指定文本匹配规则;默认规则是`MatchPattern.EQUALS`,即目标控件text属性必须严格等于给定值。
251
252####  控件相对定位
253
254**示例代码1**:查找位于文本控件`Item3_3`后面的,id是`ResourceTable.Id_switch`的Switch控件。
255
256```javascript
257let switch = await driver.findComponent(BY.id(Id_switch).isAfter(BY.text("Item3_3")))
258```
259
260通过`By.isAfter`方法,指定位于目标控件前面的特征控件属性,通过该特征控件进行相对定位。一般地,特征控件是某个具有全局唯一特征的控件(例如具有唯一的id或者唯一的text)。
261
262
263类似的,可以使用`By.isBefore`控件指定位于目标控件后面的特征控件属性,实现相对定位。
264
265### UiComponent使用说明
266
267`UiComponent`类代表了Ui界面上的一个控件,一般是通过`UiDriver.findComponent(by)`方法查找到的。通过该类的实例,用户可以获取控件属性,单击控件,滑动查找,注入文本等操作。
268
269`UiComponent`包含的常用API:
270
271| No.  | API                               | 功能描述                                     |
272| ---- | --------------------------------- | -------------------------------------------- |
273| 1    | click():Promise<void>             | 单击该控件                                   |
274| 2    | inputText(t:string):Promise<void> | 向控件中输入文本(适用于文本框控件)           |
275| 3    | scrollSearch(s:By):Promise<bool>  | 在该控件上滑动查找目标控件(适用于List等控件) |
276| 4    | getText():Promise<string>         | 获取控件text                                 |
277| 5    | getId():Promise<number>           | 获取控件id                                   |
278| 6    | getType():Promise<string>         | 获取控件类型                                 |
279| 7    | isEnabled():Promise<bool>         | 获取控件使能状态                             |
280
281`UiComponent`完整的API列表请参考其API文档。
282
283**示例代码1**:单击控件。
284
285```javascript
286let button = await driver.findComponent(BY.id(Id_button))
287await button.click()
288```
289
290**示例代码2**:通过get接口获取控件属性后,可以使用单元测试框架提供的assert*接口做断言检查。
291
292```javascript
293let component = await driver.findComponent(BY.id(Id_title))
294expect(component !== null).assertTrue()
295```
296
297**示例代码3**:在List控件中滑动查找text是`Item3_3`的子控件。
298
299```javascript
300let list = await driver.findComponent(BY.id(Id_list))
301let found = await list.scrollSearch(BY.text("Item3_3"))
302expect(found).assertTrue()
303```
304
305**示例代码4**:向输入框控件中输入文本。
306
307```javascript
308let editText = await driver.findComponent(BY.type('InputText'))
309await editText.inputText("user_name")
310```
311### 使用方式
312
313  开发者可以下载Deveco Studio创建测试工程后,在其中调用框架提供接口进行相关测试操作,测试工程创建及测试脚本执行使用指南请参见[IDE指导文档](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453)314
315### 推送Ui测试框架至设备
316
317> Ui测试框架3.1Release版本暂不随版本编译,使用时需自行编译后推送至OpenHarmony设备。后续随版本编译后,直接使用版本即可。
318
319#### 下载代码
320
321在工程test目录下执行如下命令下载测试框架仓代码。
322
323```shell
324git clone https://gitee.com/openharmony/arkXtest.git -b OpenHarmony-3.1-Release
325```
326#### 编译脚本修改
327
328修改build仓中subsystem_config.json文件,增加如下字段。
329
330```shell
331"arkXtest": {
332    "path": "test/arkXtest",
333    "name": "arkXtest"
334  },
335```
336修改productdefine_common仓中 rk3568.json文件,增加如下字段。
337```shell
338"arkXtest:arkXtest":{},
339```
340#### 构建方式
341
342```shell
343./build.sh --product-name rk3568 --build-target uitestkit
344```
345#### 推送方式
346
347```shell
348hdc_std target mount
349hdc_std shell mount -o rw,remount /
350hdc_std file send uitest /system/bin/uitest
351hdc_std file send libuitest.z.so /system/lib/module/libuitest.z.so
352hdc_std shell chmod +x /system/bin/uitest
353```
354