• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 开发自测试执行框架
2OpenHarmony为开发者提供了一套全面的开发自测试框架OHA-developer_test,开发者可根据测试需求开发相关测试用例,开发阶段提前发现缺陷,大幅提高代码质量。
3
4本文从基础环境构建,用例开发,编译以及执行等方面介绍OpenHarmony开发自测试执行框架如何运行和使用。
5## 基础环境构建
6开发自测试框架依赖于python运行环境,python版本为3.8.X,在使用测试框架之前可参阅以下方式进行配置。
7 - [环境配置](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/device-test/developer_test.md)
8 - [源码获取](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md)
9
10开发自测试框架依赖于测试调度框架testfwk_xdevice,在使用时两个框架放在同级目录
11
12## 开发自测试框架目录简介
13以下是开发自测试框架的目录层级架构,在使用开发自测试框架过程中可在相应目录查找对应组件。
14```
15test  # 测试子系统
16├── developer_test  # 开发者自测试框架
17│   ├── aw  # 测试框架的静态库
18│   ├── config  # 测试框架配置
19│   │   │ ...
20│   │   └── user_config.xml  # 用户使用配置
21│   ├── examples  # 测试用例示例
22│   ├── src  # 测试框架源码
23│   ├── third_party  # 测试框架依赖第三方组件适配
24│   ├── reports  # 测试结果报告
25│   ├── BUILD.gn  # 测试框架编译入口
26│   ├── start.bat  # 开发者测试入口(Windows)
27│   └── start.sh  # 开发者测试入口(Linux)
28└── xdevice  # 测试框架依赖组件
29```
30## 功能特性
31
32### 测试用例
33
34####  测试用例目录规划
35使用测试框架过程中,可根据以下层级关系规划测试用例目录。
36
37```
38subsystem  # 子系统
39├── partA  # 部件A
40│   ├── moduleA  # 模块A
41│   │   ├── include
42│   │   ├── src  # 业务代码
43│   │   └── test  # 测试目录
44│   │       ├── unittest  # 单元测试
45│   │       │   ├── common  # 公共用例
46│   │       │   │   ├── BUILD.gn  # 测试用例编译配置
47│   │       │   │   └── testA_test.cpp  # 单元测试用例源码
48│   │       │   ├── phone  # 手机形态用例
49│   │       │   ├── ivi  # 车机形态用例
50│   │       │   └── liteos-a  # ipcamera使用liteos内核的用例
51│   │       ├── moduletest  # 模块测试
52│   │       ...
53│   │
54│   ├── moduleB  # 模块B
55│   ├── test
56│   │   └── resource  # 依赖资源
57│   │       ├── moduleA  # 模块A
58│   │       │   ├── ohos_test.xml  # 资源配置文件
59│   │       ... └── 1.txt  # 资源
60│   │
61│   ├── bundle.json  # 编译入口配置
62│   ...
6364...
65```
66> **注意:** 测试用例根据不同设备形态差异分为通用用例和非通用用例,建议将通用用例存放在common目录下,非通用用例存放在相应设备形态目录下。
67
68####  测试用例编写
69本测试框架支持多种类型测试,针对不同测试类型提供了不同的用例编写模板以供参考。
70
71**TDD测试(C++)**
72
73- 用例源文件命名规范
74
75    测试用例源文件名称和测试套内容保持一致,文件命名采用全小写+下划线方式命名,以test结尾,具体格式为:[功能]_[子功能]_test,子功能支持向下细分。
76
77单线程示例:
78    ```
79    calculator_sub_test.cpp
80    ```
81
82- 用例示例
83    ```
84    /*
85     * Copyright (c) 2021 XXXX Device Co., Ltd.
86     * Licensed under the Apache License, Version 2.0 (the "License");
87     * you may not use this file except in compliance with the License.
88     * You may obtain a copy of the License at
89     *
90     *     http://www.apache.org/licenses/LICENSE-2.0
91     *
92     * Unless required by applicable law or agreed to in writing, software
93     * distributed under the License is distributed on an "AS IS" BASIS,
94     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95     * See the License for the specific language governing permissions and
96     * limitations under the License.
97     */
98
99    #include "calculator.h"
100    #include <gtest/gtest.h>
101
102    using namespace testing::ext;
103
104    class CalculatorSubTest : public testing::Test {
105    public:
106        static void SetUpTestCase(void);
107        static void TearDownTestCase(void);
108        void SetUp();
109        void TearDown();
110    };
111
112    void CalculatorSubTest::SetUpTestCase(void)
113    {
114        // input testsuit setup step,setup invoked before all testcases
115    }
116
117    void CalculatorSubTest::TearDownTestCase(void)
118    {
119        // input testsuit teardown step,teardown invoked after all testcases
120    }
121
122    void CalculatorSubTest::SetUp(void)
123    {
124        // input testcase setup step,setup invoked before each testcases
125    }
126
127    void CalculatorSubTest::TearDown(void)
128    {
129        // input testcase teardown step,teardown invoked after each testcases
130    }
131
132    /**
133     * @tc.name: integer_sub_001
134     * @tc.desc: Verify the sub function.
135     * @tc.type: FUNC
136     * @tc.require: issueNumber
137     */
138    HWTEST_F(CalculatorSubTest, integer_sub_001, TestSize.Level1)
139    {
140        // step 1:调用函数获取结果
141        int actual = Sub(4,0);
142
143        // Step 2:使用断言比较预期与实际结果
144        EXPECT_EQ(4, actual);
145    }
146    ```
147    详细内容介绍:
148    1. 添加测试用例文件头注释信息
149	    ```
150    	/*
151    	 * Copyright (c) 2021 XXXX Device Co., Ltd.
152    	 * Licensed under the Apache License, Version 2.0 (the "License");
153    	 * you may not use this file except in compliance with the License.
154    	 * You may obtain a copy of the License at
155    	 *
156    	 *     http://www.apache.org/licenses/LICENSE-2.0
157    	 *
158    	 * Unless required by applicable law or agreed to in writing, software
159    	 * distributed under the License is distributed on an "AS IS" BASIS,
160    	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
161    	 * See the License for the specific language governing permissions and
162    	 * limitations under the License.
163    	 */
164    	```
165    2. 引用测试框架头文件和命名空间
166	    ```
167    	#include <gtest/gtest.h>
168
169    	using namespace testing::ext;
170    	```
171    3. 添加被测试类的头文件
172	    ```
173    	#include "calculator.h"
174    	```
175    4. 定义测试套(测试类)
176	    ```
177    	class CalculatorSubTest : public testing::Test {
178    	public:
179    	    static void SetUpTestCase(void);
180    	    static void TearDownTestCase(void);
181    	    void SetUp();
182    	    void TearDown();
183    	};
184
185    	void CalculatorSubTest::SetUpTestCase(void)
186    	{
187    	    // input testsuit setup step,setup invoked before all testcases
188    	}
189
190    	void CalculatorSubTest::TearDownTestCase(void)
191    	{
192    	    // input testsuit teardown step,teardown invoked after all testcases
193    	}
194
195    	void CalculatorSubTest::SetUp(void)
196    	{
197    	    // input testcase setup step,setup invoked before each testcases
198    	}
199
200    	void CalculatorSubTest::TearDown(void)
201    	{
202    	    // input testcase teardown step,teardown invoked after each testcases
203    	}
204    	```
205	    > **注意:** 在定义测试套时,测试套名称应与编译目标保持一致,采用大驼峰风格。
206
207    5. 测试用例实现,包含用例注释和逻辑实现
208	    ```
209    	/**
210    	 * @tc.name: integer_sub_001
211    	 * @tc.desc: Verify the sub function.
212    	 * @tc.type: FUNC
213    	 * @tc.require: issueNumber
214    	 */
215    	HWTEST_F(CalculatorSubTest, integer_sub_001, TestSize.Level1)
216    	{
217    	    //step 1:调用函数获取结果
218    	    int actual = Sub(4,0);
219
220    	    //Step 2:使用断言比较预期与实际结果
221    	    EXPECT_EQ(4, actual);
222    	}
223    	```
224		> **注意:** @tc.require: 格式必须以AR/SR或issue开头: 如:issueI56WJ7
225
226多线程示例:
227    ```
228    base_object_test.cpp
229    ```
230
231- 多线程用例示例
232    ```
233    // 测试用例文件头注释信息及用例注释同单线程用例示例。
234
235    #include "base_object.h"
236    #include <gtest/gtest.h>
237	#include <gtest/hwext/gtest-multithread.h>
238	#include <unistd.h>
239
240    using namespace testing::ext;
241    using namespace testing::mt;
242
243	namespace OHOS {
244	namespace AAFwk {
245    class AAFwkBaseObjectTest : public testing::Test {......}
246
247	// Step 1:待测函数,返回阶乘结果
248	int factorial(int n)
249	{
250		int result = 1;
251		for (int i = 1; i <= n; i++) {
252			result *= i;
253		}
254		printf("Factorial Function Result : %d! = %d\n", n, result);
255		return result;
256	}
257
258	// Step 2:使用断言比较预期与实际结果
259	void factorial_test()
260	{
261		int ret = factorial(3); // 调用函数获取结果
262		std::thread::id this_id = std::this_thread::get_id();
263		std::ostringstream oss;
264		oss << this_id;
265		std::string this_id_str = oss.str();
266		long int thread_id = atol(this_id_str.c_str());
267		printf("running thread...: %ld\n", thread_id); // 输出当前线程的id
268		EXPECT_EQ(ret, 6);
269	}
270
271	HWTEST_F(AAFwkBaseObjectTest, Factorial_test_001, TestSize.Level1)
272	{
273		SET_THREAD_NUM(4);
274		printf("Factorial_test_001 BEGIN\n");
275		GTEST_RUN_TASK(factorial_test);
276		printf("Factorial_test_001 END\n");
277	}
278
279	HWMTEST_F(AAFwkBaseObjectTest, Factorial_test_002, TestSize.Level1, 6)
280	{
281		printf("Factorial_test_002 BEGIN\n");
282		factorial_test();
283		printf("Factorial_test_002 END\n");
284	}
285
286	}  // namespace AAFwk
287	}  // namespace OHOS
288
289    ```
290    详细内容介绍:
291    1. 添加测试用例文件头注释信息
292
293		> **注意:** 与单线程用例标准一致。
294
295    2. 引用测试框架头文件和命名空间
296	    ```
297    	#include <gtest/gtest.h>
298    	#include <gtest/hwext/gtest-multithread.h>
299		#include <unistd.h>
300    	using namespace testing::ext;
301   		using namespace testing::mt;
302    	```
303    3. 添加被测试类的头文件
304	    ```
305    	#include "base_object.h"
306    	```
307    4. 定义测试套(测试类)
308	    ```
309    	class AAFwkBaseObjectTest : public testing::Test {......}
310
311    	```
312	    > **注意:** 与单线程用例标准一致。
313
314    5. 测试用例实现,包含用例注释和逻辑实现
315
316	    ```
317		// Step 1:待测函数,返回阶乘结果
318		int factorial(int n)
319		{
320			int result = 1;
321			for (int i = 1; i <= n; i++) {
322				result *= i;
323			}
324			printf("Factorial Function Result : %d! = %d\n", n, result);
325			return result;
326		}
327
328		// Step 2:使用断言比较预期与实际结果
329		void factorial_test()
330		{
331			int ret = factorial(3); // 调用函数获取结果
332			std::thread::id this_id = std::this_thread::get_id();
333			std::ostringstream oss;
334			oss << this_id;
335			std::string this_id_str = oss.str();
336			long int thread_id = atol(this_id_str.c_str());
337			printf("running thread...: %ld\n", thread_id); // 输出当前线程的id
338			EXPECT_EQ(ret, 6);
339		}
340
341		// GTEST_RUN_TASK(TestFunction)多线程启动函数,参数为自定义函数。
342		// 未调用SET_THREAD_NUM()时,默认线程数10个。
343    	HWTEST_F(AAFwkBaseObjectTest, Factorial_test_001, TestSize.Level1)
344    	{
345			SET_THREAD_NUM(4); // 设置线程数量,同一测试套中可动态设置线程数。
346			printf("Factorial_test_001 BEGIN\n");
347			GTEST_RUN_TASK(factorial_test); // 启动factorial_test任务的多线程执行
348			printf("Factorial_test_001 END\n");
349    	}
350
351		// HWMTEST_F(TEST_SUITE, TEST_TC, TEST_LEVEL, THREAD_NUM)
352		// THREAD_NUM可设置用例执行的线程数量。
353		// HWMTEST_F会创建指定数量的线程并执行被测函数。
354    	HWMTEST_F(AAFwkBaseObjectTest, Factorial_test_002, TestSize.Level1, 6)
355    	{
356			printf("Factorial_test_002 BEGIN\n");
357			factorial_test();
358			printf("Factorial_test_002 END\n");
359    	}
360		// 新增多线程接口MTEST_ADD_TASK(THREAD_ID,ThreadTestFunc),注册多线程,但不在该用例中执行,之后统一执行,适合多个用例组合场景下的多线程测试。
361		// THREAD_ID从0开始定义区别不同的线程,也可以使用随机THREAD_ID,即传入RANDOM_THREAD_ID,此场景下THREAD_ID是不会重复的。
362		// 新增多线程接口MTEST_POST_RUN(),统一执行之前注册的多线程用例。
363    	```
364		> **注意:** 用例注释与单线程用例标准一致。
365
366	    在编写用例时,我们提供了四种用例模板供您选择。
367
368	    |      类型 |    描述 |
369    	| ------------| ------------|
370    	| HWTEST(A,B,C)| 用例执行不依赖Setup&Teardown时,可选取|
371    	| HWTEST_F(A,B,C)| 用例执行(不含参数)依赖于Setup&Teardown时,可选取|
372		| HWMTEST_F(A,B,C,D)| 多线程用例执行依赖于Setup&Teardown时,可选取|
373    	| HWTEST_P(A,B,C)| 用例执行(含参数)依赖于Set&Teardown时,可选取|
374
375	    其中,参数A,B,C,D的含义如下:
376	- 参数A为测试套名。
377	- 参数B为测试用例名,其命名必须遵循[功能点]_[编号]的格式,编号为3位数字,从001开始。
378	- 参数C为测试用例等级,具体分为门禁level0 以及非门禁level1-level4共五个等级,其中非门禁level1-level4等级的具体选取规则为:测试用例功能越重要,level等级越低。
379	- 参数D为多线程用例执行的线程数量设置。
380
381	    **注意:**
382	- 测试用例的预期结果必须有对应的断言。
383	- 测试用例必须填写用例等级。
384	- 测试体建议按照模板分步实现。
385	- 用例描述信息按照标准格式@tc.xxx value书写,注释信息必须包含用例名称,用例描述,用例类型,需求编号四项。其中用例测试类型@tc.type参数的选取,可参考下表。
386	- 如使用HWMTEST_F编写多线程执行用例,必须填线程数量。
387	    | 测试类型名称|类型编码|
388    	| ------------|------------|
389    	|功能测试      |FUNC|
390        |性能测试      |PERF|
391        |可靠性测试    |RELI|
392        |安全测试      |SECU|
393        |模糊测试      |FUZZ|
394
395
396**TDD测试(JS)**
397
398
399- 用例源文件命名规范
400
401    测试用例原文件名称采用大驼峰风格,以TEST结尾,具体格式为:[功能][子功能]TEST,子功能支持向下细分。
402示例:
403    ```
404    AppInfoTest.js
405    ```
406
407- 用例示例
408    ```
409    /*
410     * Copyright (C) 2021 XXXX Device Co., Ltd.
411     * Licensed under the Apache License, Version 2.0 (the "License");
412     * you may not use this file except in compliance with the License.
413     * You may obtain a copy of the License at
414     *
415     *     http://www.apache.org/licenses/LICENSE-2.0
416     *
417     * Unless required by applicable law or agreed to in writing, software
418     * distributed under the License is distributed on an "AS IS" BASIS,
419     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
420     * See the License for the specific language governing permissions and
421     * limitations under the License.
422     */
423    import app from '@system.app'
424
425    import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index'
426
427    describe("AppInfoTest", function () {
428        beforeAll(function() {
429            // input testsuit setup step,setup invoked before all testcases
430             console.info('beforeAll caled')
431        })
432
433        afterAll(function() {
434             // input testsuit teardown step,teardown invoked after all testcases
435             console.info('afterAll caled')
436        })
437
438        beforeEach(function() {
439            // input testcase setup step,setup invoked before each testcases
440             console.info('beforeEach caled')
441        })
442
443        afterEach(function() {
444            // input testcase teardown step,teardown invoked after each testcases
445             console.info('afterEach caled')
446        })
447
448        /*
449         * @tc.name:appInfoTest001
450         * @tc.desc:verify app info is not null
451         * @tc.type: FUNC
452         * @tc.require: issueNumber
453         */
454        it("appInfoTest001", 0, function () {
455            //step 1:调用函数获取结果
456            var info = app.getInfo()
457
458            //Step 2:使用断言比较预期与实际结果
459            expect(info != null).assertEqual(true)
460        })
461    })
462    ```
463    详细内容介绍:
464    1. 添加测试用例文件头注释信息
465	    ```
466    	/*
467    	 * Copyright (C) 2021 XXXX Device Co., Ltd.
468    	 * Licensed under the Apache License, Version 2.0 (the "License");
469    	 * you may not use this file except in compliance with the License.
470    	 * You may obtain a copy of the License at
471    	 *
472    	 *     http://www.apache.org/licenses/LICENSE-2.0
473    	 *
474    	 * Unless required by applicable law or agreed to in writing, software
475    	 * distributed under the License is distributed on an "AS IS" BASIS,
476    	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
477    	 * See the License for the specific language governing permissions and
478    	 * limitations under the License.
479    	 */
480    	```
481    2. 导入被测api和jsunit测试库
482	    ```
483    	import app from '@system.app'
484
485    	import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index'
486    	```
487    3. 定义测试套(测试类)
488	    ```
489    	describe("AppInfoTest", function () {
490    	    beforeAll(function() {
491    	        // input testsuit setup step,setup invoked before all testcases
492    	         console.info('beforeAll caled')
493    	    })
494
495    	    afterAll(function() {
496    	         // input testsuit teardown step,teardown invoked after all testcases
497    	         console.info('afterAll caled')
498    	    })
499
500    	    beforeEach(function() {
501    	        // input testcase setup step,setup invoked before each testcases
502    	         console.info('beforeEach caled')
503    	    })
504
505    	    afterEach(function() {
506    	        // input testcase teardown step,teardown invoked after each testcases
507    	         console.info('afterEach caled')
508    	    })
509    	```
510    4. 测试用例实现
511	    ```
512    	/*
513    	 * @tc.name:appInfoTest001
514    	 * @tc.desc:verify app info is not null
515    	 * @tc.type: FUNC
516    	 * @tc.require: issueNumber
517    	 */
518    	 it("appInfoTest001", 0, function () {
519    	    //step 1:调用函数获取结果
520            var info = app.getInfo()
521
522            //Step 2:使用断言比较预期与实际结果
523            expect(info != null).assertEqual(true)
524    	 })
525    	```
526		> **注意:** @tc.require: 格式必须以AR/SR或issue开头: 如:issueI56WJ7
527
528**Fuzz测试**
529
530[Fuzz用例编写规范](https://gitee.com/openharmony/testfwk_developer_test/blob/master/libs/fuzzlib/README_zh.md)
531
532
533**Benchmark测试**
534
535[Benchmark用例编写规范](https://gitee.com/openharmony/testfwk_developer_test/blob/master/libs/benchmark/README_zh.md)
536
537
538#### 测试用例编译文件编写
539根据测试用例目录规划,当执行某一用例时,测试框架会根据编译文件逐层查找,最终找到所需用例进行编译。下面通过不同示例来讲解gn文件如何编写。
540
541**TDD测试**
542
543针对不同语言,下面提供不同的编译模板以供参考。
544
545- **C++用例编译配置示例**
546
547    ```
548    # Copyright (c) 2021 XXXX Device Co., Ltd.
549
550    import("//build/test.gni")
551
552    module_output_path = "developer_test/calculator"
553
554    config("module_private_config") {
555      visibility = [ ":*" ]
556
557      include_dirs = [ "../../../include" ]
558    }
559
560    ohos_unittest("CalculatorSubTest") {
561      module_out_path = module_output_path
562
563      sources = [
564        "../../../include/calculator.h",
565        "../../../src/calculator.cpp",
566      ]
567
568      sources += [ "calculator_sub_test.cpp" ]
569
570      configs = [ ":module_private_config" ]
571
572      deps = [ "//third_party/googletest:gtest_main" ]
573    }
574
575    group("unittest") {
576      testonly = true
577      deps = [":CalculatorSubTest"]
578    }
579    ```
580    详细内容如下:
581
582	1. 添加文件头注释信息
583        ```
584    	# Copyright (c) 2021 XXXX Device Co., Ltd.
585    	```
586	2. 导入编译模板文件
587        ```
588    	import("//build/test.gni")
589    	```
590    3. 指定文件输出路径
591    	```
592    	module_output_path = "developer_test/calculator"
593    	```
594    	> **说明:** 此处输出路径为部件/模块名。
595
596    4. 配置依赖包含目录
597
598    	```
599    	config("module_private_config") {
600    	  visibility = [ ":*" ]
601
602    	  include_dirs = [ "../../../include" ]
603    	}
604    	```
605    	> **说明:** 一般在此处对相关配置进行设置,在测试用例编译脚本中可直接引用。
606
607    5. 指定测试用例编译目标输出的文件名称
608
609    	```
610    	ohos_unittest("CalculatorSubTest") {
611    	}
612    	```
613    6. 编写具体的测试用例编译脚本(添加需要参与编译的源文件、配置和依赖)
614    	```
615    	ohos_unittest("CalculatorSubTest") {
616    	  module_out_path = module_output_path
617    	  sources = [
618    	    "../../../include/calculator.h",
619    	    "../../../src/calculator.cpp",
620    	    "../../../test/calculator_sub_test.cpp"
621    	  ]
622    	  sources += [ "calculator_sub_test.cpp" ]
623    	  configs = [ ":module_private_config" ]
624    	  deps = [ "//third_party/googletest:gtest_main" ]
625    	}
626    	```
627
628        > **说明:根据测试类型的不同,在具体编写过程中可选择不同的测试类型:**
629    	> - ohos_unittest:单元测试
630    	> - ohos_js_unittest: FA模型js用例单元测试
631		> - ohos_js_stage_unittest: stage模型ets用例单元测试
632    	> - ohos_moduletest:模块测试
633    	> - ohos_systemtest:系统测试
634    	> - ohos_performancetest:性能测试
635    	> - ohos_securitytest:安全测试
636    	> - ohos_reliabilitytest:可靠性测试
637    	> - ohos_distributedtest:分布式测试
638
639    7. 对目标测试用例文件进行条件分组
640
641    	```
642    	group("unittest") {
643    	  testonly = true
644    	  deps = [":CalculatorSubTest"]
645    	}
646    	```
647    	> **说明:** 进行条件分组的目的在于执行用例时可以选择性的执行某一种特定类型的用例。
648
649- ** FA模型JavaScript用例编译配置示例**
650
651    ```
652    # Copyright (C) 2021 XXXX Device Co., Ltd.
653
654    import("//build/test.gni")
655
656    module_output_path = "developer_test/app_info"
657
658    ohos_js_unittest("GetAppInfoJsTest") {
659      module_out_path = module_output_path
660
661      hap_profile = "./config.json"
662      certificate_profile = "//test/developer_test/signature/openharmony_sx.p7b"
663    }
664
665    group("unittest") {
666      testonly = true
667      deps = [ ":GetAppInfoJsTest" ]
668    }
669    ```
670
671    详细内容如下:
672
673    1. 添加文件头注释信息
674
675    	```
676    	# Copyright (C) 2021 XXXX Device Co., Ltd.
677    	```
678    2. 导入编译模板文件
679
680    	```
681    	import("//build/test.gni")
682    	```
683    3. 指定文件输出路径
684
685    	```
686    	module_output_path = "developer_test/app_info"
687    	```
688    	> **说明:** 此处输出路径为部件/模块名。
689
690    4. 指定测试用例编译目标输出的文件名称
691
692    	```
693    	ohos_js_unittest("GetAppInfoJsTest") {
694    	}
695    	```
696    	> **说明:**
697    	>- 使用模板ohos_js_unittest定义js测试套,注意与C++用例区分。
698    	>- js测试套编译输出文件为hap类型,hap名为此处定义的测试套名,测试套名称必须以JsTest结尾。
699
700    5. 指定hap包配置文件config.json和签名文件,两个配置为必选项
701
702    	```
703    	ohos_js_unittest("GetAppInfoJsTest") {
704    	  module_out_path = module_output_path
705
706    	  hap_profile = "./config.json"
707    	  certificate_profile = "//test/developer_test/signature/openharmony_sx.p7b"
708    	}
709    	```
710    	 config.json为hap编译所需配置文件,需要开发者根据被测sdk版本配置“target”项,其余项可默认,具体如下所示:
711
712    	```
713    	{
714    	  "app": {
715    	    "bundleName": "com.example.myapplication",
716    	    "vendor": "example",
717    	    "version": {
718    	      "code": 1,
719    	      "name": "1.0"
720    	    },
721    	    "apiVersion": {
722    	           "compatible": 4,
723    	         "target": 5     // 根据被测sdk版本进行修改,此例为sdk5
724    	    }
725    	  },
726    	  "deviceConfig": {},
727    	  "module": {
728    	    "package": "com.example.myapplication",
729    	    "name": ".MyApplication",
730    	    "deviceType": [
731    	      "phone"
732    	    ],
733    	    "distro": {
734    	      "deliveryWithInstall": true,
735    	      "moduleName": "entry",
736    	      "moduleType": "entry"
737    	    },
738    	    "abilities": [
739    	      {
740    	      "skills": [
741    	          {
742    	            "entities": [
743    	              "entity.system.home"
744    	            ],
745    	            "actions": [
746    	              "action.system.home"
747    	            ]
748    	          }
749    	        ],
750    	        "name": "com.example.myapplication.MainAbility",
751    	        "icon": "$media:icon",
752    	        "description": "$string:mainability_description",
753    	        "label": "MyApplication",
754    	        "type": "page",
755    	        "launchType": "standard"
756    	      }
757    	    ],
758    	    "js": [
759    	      {
760    	        "pages": [
761    	          "pages/index/index"
762    	        ],
763    	        "name": "default",
764    	          "window": {
765    	             "designWidth": 720,
766    	             "autoDesignWidth": false
767    	          }
768    	        }
769    	      ]
770    	    }
771    	  }
772    	```
773    6. 对目标测试用例文件进行条件分组
774    	```
775    	group("unittest") {
776    	  testonly = true
777    	  deps = [ ":GetAppInfoJsTest" ]
778    	}
779    	```
780    	> **说明:** 进行条件分组的目的在于执行用例时可以选择性的执行某一种特定类型的用例。
781
782- ** stage模型ets用例编译配置示例**
783
784    ```
785    # Copyright (C) 2022 XXXX Device Co., Ltd.
786
787    import("//build/test.gni")
788
789    want_output_path = "developer_test/stage_test"
790
791    ohos_js_stage_unittest("ActsBundleMgrStageEtsTest") {
792      hap_profile = "entry/src/main/module.json"
793      deps = [
794        ":actbmsstageetstest_js_assets",
795        ":actbmsstageetstest_resources",
796      ]
797      ets2abc = true
798      certificate_profile = "signature/openharmony_sx.p7b"
799      hap_name = "ActsBundleMgrStageEtsTest"
800      subsystem_name = "developer_test"
801      part_name = "stage_test"  // 部件名称
802      module_out_path = want_output_path   // 必须定义输出路径
803    }
804    ohos_app_scope("actbmsstageetstest_app_profile") {
805      app_profile = "AppScope/app.json"
806      sources = [ "AppScope/resources" ]
807    }
808    ohos_js_assets("actbmsstageetstest_js_assets") {
809      source_dir = "entry/src/main/ets"
810    }
811    ohos_resources("actbmsstageetstest_resources") {
812      sources = [ "entry/src/main/resources" ]
813      deps = [ ":actbmsstageetstest_app_profile" ]
814      hap_profile = "entry/src/main/module.json"
815    }
816    group("unittest") {
817      testonly = true
818      deps = []
819      deps += [ ":ActsBundleMgrStageEtsTest" ]
820    }
821    ```
822    > **说明:** 进行条件分组的目的在于执行用例时可以选择性的执行某一种特定类型的用例。
823
824**编译入口配置文件bundle.json**
825
826当完成用例编译配置文件编写后,需要进一步编写部件编译配置文件,以关联到具体的测试用例。
827```
828"build": {
829    "sub_component": [
830		"//test/testfwk/developer_test/examples/app_info:app_info",
831		"//test/testfwk/developer_test/examples/detector:detector",
832		"//test/testfwk/developer_test/examples/calculator:calculator"
833    ],
834    "inner_list": [
835		{
836			"header": {
837				"header_base": "////test/testfwk/developer_test/examples/detector/include",
838				"header_files": [
839					"detector.h"
840				]
841		},
842		"name": "//test/testfwk/developer_test/examples/detector:detector"
843	  }
844    ],
845    "test": [ //配置模块calculator下的test
846      "//test/testfwk/developer_test/examples/app_info/test:unittest",
847      "//test/testfwk/developer_test/examples/calculator/test:unittest",
848      "//test/testfwk/developer_test/examples/calculator/test:fuzztest"
849 }
850```
851> **说明:** test_list中配置的是对应模块的测试用例。
852
853#### 测试用例资源配置
854测试依赖资源主要包括测试用例在执行过程中需要的图片文件,视频文件、第三方库等对外的文件资源,目前只支持静态资源的配置。
855
856依赖资源文件配置步骤如下:
8571. 在部件的test目录下创建resource目录,在resource目录下创建对应的模块,在模块目录中存放该模块所需要的资源文件
858
8592. 在resource目录下对应的模块目录中创建一个ohos_test.xml文件,文件内容格式如下:
860	```
861	<?xml version="1.0" encoding="UTF-8"?>
862	<configuration ver="2.0">
863	    <target name="CalculatorSubTest">
864	        <preparer>
865	            <option name="push" value="test.jpg -> /data/test/resource" src="res"/>
866	            <option name="push" value="libc++.z.so -> /data/test/resource" src="out"/>
867	        </preparer>
868	    </target>
869	</configuration>
870	```
871	>**说明:**若某些push上去的二进制文件需要增量生成数据字典,则新增一行:
872	```
873    <option name="shell" value="hilog -d /设备中的二进制文件路径"/>
874    // 例如
875    <option name="shell" value="hilog -d /data/test/resource/test.z.so"/>
876	```
8773. 在测试用例的编译配置文件中定义resource_config_file进行指引,用来指定对应的资源文件ohos_test.xml
878	```
879	ohos_unittest("CalculatorSubTest") {
880	  resource_config_file = "//system/subsystem/partA/test/resource/calculator/ohos_test.xml"
881	}
882	```
883	>**说明:**
884	>- target_name: 测试套的名称,定义在测试目录的BUILD.gn中。preparer: 表示该测试套执行前执行的动作。
885	>- src="res": 表示测试资源位于test目录下的resource目录下,src="out":表示位于out/release/$(部件)目录下。
886
887### 测试用例执行
888在执行测试用例之前,针对用例使用设备的不同,需要对相应配置进行修改,修改完成即可执行测试用例。
889
890#### user_config.xml配置
891```
892<user_config>
893  <build>
894    <!-- 是否编译demo用例, 默认为false,如果需要编译demo可修改为true -->
895    <example>false</example>
896    <!-- 是否编译版本, 默认为false -->
897    <version>false</version>
898    <!-- 是否编译测试用例, 默认为true,若已完成编译,再执行用例之前可修改为false,防止重新编译 -->
899    <testcase>true</testcase>
900	<!-- 在编译测试用例的情况下,选择编译target_cpu是64位的还是32位的,默认为空(32bit)可以选择: arm64 -->
901    <parameter>
902       <target_cpu></target_cpu>
903    </parameter>
904  </build>
905  <environment>
906    <!-- 配置远程映射机器的IP及端口,以支持HDC连接的设备 -->
907    <device type="usb-hdc">
908      <ip></ip>
909      <port></port>
910      <sn></sn>
911    </device>
912    <!-- 配置设备的串口信息,以支持串口连接的设备 -->
913    <device type="com" label="ipcamera">
914      <serial>
915        <com></com>
916        <type>cmd</type>
917        <baud_rate>115200</baud_rate>
918        <data_bits>8</data_bits>
919        <stop_bits>1</stop_bits>
920        <timeout>1</timeout>
921      </serial>
922    </device>
923  </environment>
924  <!-- 配置测试用例路径,若测试用例未编译,即<testcase>标签属性为true时,此处默认不填写;若编译已完成,需在此处指定测试用例的实际路径 -->
925  <test_cases>
926    <dir></dir>
927  </test_cases>
928  <!-- 配置覆盖率编译路径 -->
929  <coverage>
930    <outpath></outpath>
931  </coverage>
932  <!-- NFS挂载信息配置,被测设备仅支持串口连接时配置,指定NFS的映射路径,host_dir为PC侧的NFS目录,board_dir为板侧创建的目录 -->
933  <NFS>
934    <host_dir></host_dir>
935    <mnt_cmd></mnt_cmd>
936    <board_dir></board_dir>
937  </NFS>
938</user_config>
939
940```
941
942>**说明:** 在执行测试用例之前,若使用HDC连接设备,用例仅需配置设备IP和端口号即可,其余信息均默认不修改。
943
944#### Windows环境执行
945##### 测试用例编译
946
947由于Windows环境下无法实现用例编译,因此执行用例前需要在Linux环境下进行用例编译,用例编译命令:
948```
949./build.sh --product-name {product_name} --build-target make_test
950```
951>说明:
952> - product-name:指定编译产品名称。
953> - build-target:指定所需编译用例,make_test表示指定全部用例,实际开发中可指定特定用例。
954
955编译完成后,测试用例将自动保存在out/ohos-arm-release/packages/phone/tests目录下。
956
957##### 搭建执行环境
9581. 在Windows环境创建测试框架目录Test,并在此目录下创建testcase目录
959
9602. 从Linux环境拷贝测试框架developer_test和xdevice到创建的Test目录下,拷贝编译好的测试用例到testcase目录下
961
962	>**说明:** 将测试框架及测试用例从Linux环境移植到Windows环境,以便后续执行。
963
9643. 修改user_config.xml
965	```
966	<build>
967	  <!-- 由于测试用例已编译完成,此标签属性需改为false -->
968	  <testcase>false</testcase>
969	</build>
970	<test_cases>
971	  <!-- 由于已将测试用例拷贝到Windows环境下,测试用例输出路径发生改变,需要修改为拷贝后所存放的路径 -->
972	  <dir>D:\Test\testcase\tests</dir>
973	</test_cases>
974	```
975	>**说明:** `<testcase>`标签表示是否需要编译用例;`<dir>`标签表示测试用例查找路径。
976
977##### 执行用例
9781. 启动测试框架
979	```
980	start.bat
981	```
9822. 选择产品形态
983
984    进入测试框架,系统会自动提示您选择产品形态,请根据实际的开发板进行选择。
985
986	如需手动添加,请在config/framework_config.xml的\<productform\>标签内增加产品项。
987
9883. 执行测试用例
989
990    当选择完产品形态,可参考如下指令执行TDD测试用例。
991	```
992	run -t UT
993	run -t UT -tp PartName
994	run -t UT -tp PartName -tm TestModuleName
995	run -t UT -tp ability_base -ts base_object_test
996	run -t UT -tp PartName -tm TestModuleName -ts CalculatorSubTest
997	run -t UT -ts base_object_test
998	run -t UT -ts base_object_test -tc AAFwkBaseObjectTest.BaseObject_test_001
999	run -t UT -ts CalculatorSubTest -tc CalculatorSubTest.interger_sub_00l
1000	run -t UT -cov coverage
1001	run -t UT -ra random
1002	run -t UT -tp PartName -pd partdeps
1003	run -t UT -ts base_object_test --repeat 5
1004	run -hl
1005	run -rh 3
1006	run --retry
1007	```
1008
1009
1010	执行命令参数说明:
1011	```
1012	-t [TESTTYPE]: 指定测试用例类型,有UT,MST,ST,PERF,FUZZ,BENCHMARK,另外还有ACTS,HATS等。(必选参数)
1013	-tp [TESTPART]: 指定部件,可独立使用。
1014	-tm [TESTMODULE]: 指定模块,不可独立使用,需结合-tp指定上级部件使用。
1015	-ts [TESTSUITE]: 指定测试套,可独立使用。
1016	-tc [TESTCASE]: 指定测试用例,同时需要注明测试套内class名称,不可独立使用,需结合-ts指定上级测试套使用。
1017	-cov [COVERAGE]: 覆盖率执行参数。
1018	-h : 帮助命令
1019	-ra [random]: c++用例乱序执行参数
1020	-pd [partdeps]: 二级依赖部件执行参数
1021	--repeat : 支持设置用例执行次数。
1022	-hl [HISTORYLIST]: 显示最近10条测试用例,超过10条,只显示最近10条。
1023	-rh [RUNHISTORY]: 执行历史记录的第几条记录运行
1024	--retry:检查上次运行结果,如果有失败用例则重复测试
1025	```
1026
1027
1028#### Linux环境执行
1029##### 远程端口映射
1030为了在Linux远程服务器以及Linux虚拟机两种环境下执行测试用例,需要对端口进行远程映射,以实现与设备的数据通路连接。具体操作如下:
10311. HDC Server指令:
1032	```
1033	hdc kill
1034	hdc -m -s 0.0.0.0:8710
1035	```
1036	>**说明:** IP和端口号为默认值。
1037
10382. HDC Client指令:
1039	```
1040	hdc -s xx.xx.xx.xx:8710 list targets
1041	```
1042	>**说明:** 此处IP填写设备侧IP地址。
1043
1044##### 执行用例
10451. 启动测试框架
1046	```
1047	./start.sh
1048	```
10492. 选择产品形态
1050
1051    进入测试框架,系统会自动提示您选择产品形态,请根据实际的开发板进行选择。
1052
1053	若需要自测试框架编译测试用例,且没有找到需要的产品形态需手动添加,请在config/framework_config.xml的\<productform\>标签内增加产品项。
1054
1055	```
1056	<framework_config>
1057	 <productform>
1058	  <option name="ipcamera_hispark_aries" />
1059	  <option name="ipcamera_hispark_taurus" />
1060	  <option name="wifiiot_hispark_pegasus" />
1061	  <option name="" />
1062	 </productform>
1063	</framework_config>
1064
1065	```
1066
10673. 执行测试用例
1068
1069    1)TDD命令
1070
1071    测试框架在执行用例时会根据指令找到所需用例,自动实现用例编译,执行过程,完成自动化测试。
1072	```
1073	run -t UT
1074	run -t UT -tp PartName
1075	run -t UT -tp PartName -tm TestModuleName
1076	run -t UT -tp ability_base -ts base_object_test
1077	run -t UT -tp PartName -tm TestModuleName -ts CalculatorSubTest
1078	run -t UT -ts base_object_test
1079	run -t UT -ts base_object_test -tc AAFwkBaseObjectTest.BaseObject_test_001
1080	run -t UT -ts CalculatorSubTest -tc CalculatorSubTest.interger_sub_00l
1081	run -t -cov coverage
1082	run -t UT -ra random
1083	run -t UT -tp PartName -pd partdeps
1084	run -t UT -ts base_object_test --repeat 5
1085	run -hl
1086	run -rh 3
1087	run --retry
1088	```
1089	执行命令参数说明:
1090	```
1091	-t [TESTTYPE]: 指定测试用例类型,有UT,MST,ST,PERF,FUZZ,BENCHMARK等。(必选参数)
1092	-tp [TESTPART]: 指定部件,可独立使用。
1093	-tm [TESTMODULE]: 指定模块,不可独立使用,需结合-tp指定上级部件使用。
1094	-ts [TESTSUITE]: 指定测试套,可独立使用。
1095	-tc [TESTCASE]: 指定测试用例,同时需要注明测试套内class名称,不可独立使用,需结合-ts指定上级测试套使用。
1096	-cov [COVERAGE]: 覆盖率执行参数。
1097	-h : 帮助命令
1098	-ra [random]: c++用例乱序执行参数
1099	-pd [partdeps]: 二级依赖部件执行参数
1100	--repeat : 支持设置用例执行次数。
1101	-hl [HISTORYLIST]: 显示最近10条测试用例,超过10条,只显示最近10条。
1102	-rh [RUNHISTORY]: 执行历史记录的第几条记录运行
1103	--retry:检查上次运行结果,如果有失败用例则重复测试
1104	```
1105
1106	在linux下可以使用help命令查看有哪些产品形态、测试类型、支持的子系统、部件
1107	```
1108	查看帮助命令:help
1109	查看show命令:help show
1110	查看支持的设备形态:   show productlist
1111	查看支持的测试类型:   show typelist
1112	查看支持的测试子系统: show subsystemlist
1113	查看支持的测试部件:   show partlist
1114	```
1115	2)ACTS/HATS命令
1116
1117	当选择完产品形态,可以参考如下执行ACTS或HATS测试用例
1118	```
1119	run -t ACTS
1120	run -t HATS
1121	run -t ACTS -ss arkui
1122	run -t ACTS -ss arkui, modulemanager
1123	run -t ACTS -ss arkui -ts ActsAceEtsTest
1124	run -t HATS -ss telephony -ts HatsHdfV1RilServiceTest
1125	run -t ACTS -ss arkui -tp ActsPartName
1126	run -t ACTS -ss arkui -ts ActsAceEtsTest,ActsAceEtsResultTest
1127	run -t HATS -ss powermgr -ts HatsPowermgrBatteryTest,HatsPowermgrThermalTest
1128	run -t ACTS -ss arkui -ts ActsAceEtsTest -ta class:alphabetIndexerTest#alphabetIndexerTest001
1129	run -t ACTS -ss arkui -ts ActsAceEtsTest -ta class:alphabetIndexerTest#alphabetIndexerTest001 --repeat 2
1130	run -hl
1131	run -rh 1
1132	run --retry
1133	```
1134	执行命令参数说明,ACTS和HATS命令参数一致,与TDD有所不同:
1135	```
1136	-t [TESTTYPE]: 指定测试用例类型,有ACTS,HATS等。(必选参数)
1137	-ss [SUBSYSTEM]: 指定子系统,可单独使用,且可以执行多个子系统,用逗号隔开。
1138	-tp [TESTPART]: 指定部件,可独立使用。
1139	-ts [TESTSUITE]: 指定测试套,可独立使用,且可以执行多个测试套,用逗号隔开。
1140	-ta [TESTARGS]: 指定测试类测试方法,需结合-ts指定上级测试套使用。
1141	--repeat : 支持设置用例执行次数。
1142	-hl [HISTORYLIST]: 显示最近10条测试用例,超过10条,只显示最近10条。
1143	-rh [RUNHISTORY]: 执行历史记录的第几条记录运行
1144	--retry:检查上次运行结果,如果有失败用例则重复测试
1145	```
1146
1147### 测试报告日志
1148当执行完测试指令,控制台会自动生成测试结果,若需要详细测试报告您可在相应的数据文档中进行查找。
1149
1150#### 测试结果
1151测试结果输出根路径如下:
1152```
1153test/developer_test/reports/xxxx_xx_xx_xx_xx_xx
1154```
1155>**说明:** 测试报告文件目录将自动生成。
1156
1157该目录中包含以下几类结果:
1158| 类型 | 描述|
1159| ------------ | ------------ |
1160| result/ |测试用例格式化结果|
1161| log/plan_log_xxxx_xx_xx_xx_xx_xx.log | 测试用例日志 |
1162| summary_report.html | 测试报告汇总 |
1163| details_report.html | 测试报告详情 |
1164
1165#### 测试框架日志
1166```
1167reports/platform_log_xxxx_xx_xx_xx_xx_xx.log
1168```
1169
1170### 覆盖率用户指导
11711. (可选执行)为了屏蔽非核心代码产生的冗余分支数据,可以在源码编译之前进入/test/testfwk/developer_test/localCoverage/restore_comment目录下执行:
1172
1173       python3 build_before_generate.py
1174
1175   选择对应的部件,执行命令例如:
1176
1177       run -tp partname
1178       run -tp partname1 partname2
11792. 编译版本之前首先修改编译选项,涉及到自己子系统的build.gn文件cflags或者cflags_cc及ldflags选项都需要加--coverage字段:
1180
1181       ldflags = [ "--coverage" ]
1182       C:   cflags = [ "--coverage" ]
1183       C++: cflags_cc = [ "--coverage" ]
1184
1185**推荐:**     也可以参考窗口子系统的方式(推荐这种方式),参考链接:https://gitee.com/openharmony/window_window_manager/pulls/1274/files
11863. 执行覆盖率需要安装以下依赖包:
1187
1188       1)安装lcov, 安装命令:sudo apt install lcov
1189       2)安装dos2unix, 安装命令:apt install dos2unix.
1190       3)安装lxml, 安装命令: pip install lxml
1191       4)安装selectolax, 安装命令: pip install selectolax
1192       5)安装CppHeaderParser, 安装命令 pip install CppHeaderParser
1193
11944. 远程映射设备,修改usr_config.xml中的ip号,设备映射方式查看上面介绍的远程端口映射,
1195
1196```
1197    <!-- 配置远程映射机器的IP(设备挂载的pc的ip) -->
1198    <device type="usb-hdc">
1199      <ip></ip>
1200      <port></port>
1201      <sn></sn>
1202    </device>
1203```
12045. 执行
1205
1206   ./start.sh
1207
1208       命令例如下:
1209       run -t UT -tp 部件名 -cov coverage
1210       run -t UT -ss 子系统名 -cov coverage
1211       run -t UT -ss 子系统名 -tp 部件名 -cov coverage
1212       run -t UT MST ST -tp 部件名 -cov coverage
1213
1214> **注意:** 必须添加 -cov coverage 参数
1215
12166. 覆盖率报告路径
1217
1218   代码覆盖率报告:/test/testfwk/developer_test/localCoverage/codeCoverage/results/coverage/reports/cxx/html
1219
1220   接口覆盖率报告:/test/testfwk/developer_test/localCoverage/interfaceCoverage/results/coverage/interface_kits/html
1221### 涉及仓
1222
1223[test\_xdevice](https://gitee.com/openharmony/testfwk_xdevice)
1224
1225## 发布版本说明
1226
1227| 发布版本号 | 发布功能说明                                                 |
1228| ---------- | ------------------------------------------------------------ |
1229| 3.2.1.0    | 1、增加框架对接执行ACTS测试用例能力<br />2、增加ACTS多种颗粒度执行能力,如子系统、部件等 |
1230| 3.2.2.0    | 1、增加测试任务统计能力,最多统计10个任务<br />2、增加按照指定测试任务ID执行测试任务能力<br />3、增加复测上次任务失败用例能力 |
1231| 3.2.3.0 | 1、增加覆盖率执行<br />                           |
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250