#跟着小白一起学鸿蒙# [三]手写一个测试用例 原创 精华
作者:王石,胡瑞涛
开源鸿蒙测试初识
在**《#跟着小白一起学鸿蒙# [一]运行OpenHarmony》**里我们提及了如何编译和运行测试套件,这一节我们着重查看如何编写测试套件,编译并测试。
1. 目录结构
//目录位置:[鸿蒙代码]/test
.
├── arkXtest //js测试框架和ui测试框架
│ ├── jsunit
│ └── uitest
├── developertest //开发测试组件
│ ├── aw
│ ├── config
│ ├── examples
│ ├── src
│ └── third_party
├── wukong //稳定性测试工具,冒烟测试
│ ├── common
│ ├── component_event
│ ├── input_factory
│ ├── report
│ ├── shell_command
│ └── test_flow
├── xdevice //测试框架核心,提供执行用例的相关服务
│ ├── BUILD.gn
│ ├── extension
│ ├── src
└── xts //兼容性测试套件
├── acts //应用兼容性测试套件
├── dcts //分布式兼容性测试套件
├── hats //硬件兼容性测试套件
└── tools
2.测试套件结构
我们选取比较简单的应用兼容性测试套件为例:
.
├── BUILD.gn //编译脚本
├── comm.gni //编译配置
├── src
│ ├── ActsLibuvTestSuite.cpp //具体测试套件源文件
│ ├── ActsLibuvTestSuite.h //具体测试套件头文件
└── Test.json //测试套件执行配置
-
import("//test/xts/tools/build/suite.gni") import("//test/xts/acts/graphic/libuv/comm.gni") ohos_moduletest_suite("ActsLibuvTestSuite”) { sources = [ "src/ActsLibuvTestSuite.cpp", ] include_dirs = [ "//test/xts/acts/graphic/libuv/src" ] cflags = [ "-Wno-error" ] }
- BUILD.gn是鸿蒙的主要编译文件,以脚本的方式提供以下主要几种编译方式:
- ohos_static_library(“静态库名称”)
- ohos_shared_library(“动态库名称”)
- ohos_ndk_library(“ndk名称”)
- ohos_executable(“可执行文件名称”)
- ohos_moduletest_suite(“模块测试suite名称”)
- ohos_hap_suite(“hap测试suite名称”)
- ohos_js_hap_suite(“js测试suite名称”)
- ohos_shell_app_suite(“脚本测试suite名称”)
- ohos_prebuilt_suite(“预编译测试suite名称”)
-
BUILD.gn主要编写格式如下
sources = [ "源文件", ] include_dirs = [ "头文件目录", ], deps = [ "依赖库路径:依赖库名称", ] configs = [ "配置文件路径:配置文件名称" ]
具体解释如下:
-
sources:对应的就是需要编译的源文件;
-
include_dirs:对应的就是编译中的头文件的路径;
-
deps:对应的此程序依赖的其他的库,比如引入hilog,则增加 “//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog”,
-
configs: 对应编译的flags或者宏定义,如
config("XX_config") { cflags_cc = [ "-Wno-conversion", "-Wno-unused-function", ] defines = deqp_common_defines defines += [ "_XOPEN_SOURCE=600" ] }
-
-
编译配置文件-comm.gni
import("//test/xts/tools/build/suite.gni") common_include = [ "//test/xts/acts/graphic/libuv/src", ] common_depends = [ "//third_party/libuv:uv_static", ]
编译配置文件可以将共同的BUILD.gn内容放置在此,供其他gn文件或者gni文件使用
-
具体测试套件源文件
#include <gtest/gtest.h> #include "ActsLibuvTestSuite.h" namespace OHOS { using namespace std; using namespace testing::ext; // Preset action of the test suite, which is executed before the first test case void ActsLibuvTestSuite::SetUpTestCase(void) { } // Test suite cleanup action, which is executed after the last test case void ActsLibuvTestSuite::TearDownTestCase(void) { } // Preset action of the test case void ActsLibuvTestSuite::SetUp() { } // Cleanup action of the test case void ActsLibuvTestSuite::TearDown() { } HWTEST_F(ActsLibuvTestSuite, testLibuvTestCase001, Function | MediumTest | Level2) { printf("------start ActsLibuvTestSuite------\n"); EXPECT_TRUE(true); printf("------end ActsLibuvTestSuite------\n"); } HWTEST_F(ActsLibuvTestSuite, testLibuvTestCase002, Function | MediumTest | Level2) { printf("------start ActsLibuvTestSuite------\n"); EXPECT_TRUE(false); printf("------end ActsLibuvTestSuite------\n"); } }
- 我们选取的此测试套件是模块测试套件,所以使用gtest测试框架进行测试
- gtest测试框架采用TestSuite + TestCase的组成方式,所以我们定义了ActsLibuvTestSuite作为测试Suite,然后添加两个testLibuvTestCase001,testLibuvTestCase002作为测试Case
- 判断一个测试是否通过可以用EXPECT_TRUE(true),EXPECT_TRUE(false)进行验证,其他还可以使用的断言如下:
- EXPECT_TRUE(condition)
- EXPECT_FALSE(condition)
- EXPECT_EQ(val1, val2)
- EXPECT_NE(val1, val2)
- EXPECT_LE(val1, val2)
- EXPECT_LT(val1, val2)
- EXPECT_GE(val1, val2)
- EXPECT_GT(val1, val2)
- EXPECT_STREQ(val1, val2)
- EXPECT_STRNE(s1, s2)
- EXPECT_STRCASEEQ(s1, s2)
- EXPECT_STRCASENE(s1, s2)
- EXPECT_FLOAT_EQ(val1, val2)
- EXPECT_DOUBLE_EQ(val1, val2)
-
具体测试套件头文件
#ifndef LIBUV_TESTCASE_H #define LIBUV_TESTCASE_H #include <gtest/gtest.h> namespace OHOS { class ActsLibuvTestSuite : public testing::Test { public: protected: // Preset action of the test suite, which is executed before the first test case static void SetUpTestCase(void); // Test suite cleanup action, which is executed after the last test case static void TearDownTestCase(void); // Preset action of the test case virtual void SetUp(); // Cleanup action of the test case virtual void TearDown(); }; } // namespace OHOS #endif // LIBUV_TESTCASE_H
-
测试套件执行配置文件
{ "description": "Config for ActsLibuvTestSuite test cases", "driver": { "module-name": "ActsLibuvTestSuite", "native-test-timeout": "120000", "native-test-device-path": "/data/local/tmp", "runtime-hint": "100s", "type": "CppTest" }, "kits": [ { "pre-push" : [ ], "post-push" : [ "chmod -R 777 /data/local/tmp/*" ], "push": [ "ActsLibuvTestSuite->/data/local/tmp/ActsLibuvTestSuite" ], "type": "PushKit" }, { "type": "ShellKit", "run-command": [ "remount", "mkdir /data/test", "cd /data/local/tmp" ] } ] }
测试套件配置文件是伴随测试套件运行的文件,在执行测试套件的时候,xdevice根据配置文件的具体命令执行测试用例,详细说明如下:
- “description”:测试套件的文字说明
- “driver”: 测试套件执行驱动配置
- “module-name”: 配置测试套件名称
- “native-test-timeout”: 套件超时设置
- “native-test-device-path”: 套件运行目录
- “runtime-hint”: 套件执行时间预估
- “type”: 套件类型
- “kits”: 测试套件工具配置
- “PushKit”:传送工具
- “pre-push”:从上位机推送到设备前的准备工作;
- “push”: 从上位机推送到设备的动作;
- “post-push”: 上位机推送后需要做的动作;
- “ShellKit”:运行工具
- “run-command”: 执行测试套件前需要配置的命令
- “PushKit”:传送工具
3.编译测试套件
上面写的测试用例需要有一个入口进行加载,在此文章我们选取graphic的gn进行依赖添加
路径:test/xts/acts/graphic/BUILD.gn import("//build/ohos_var.gni") group("graphic") { testonly = true if (is_standard_system) { deps = [ "webGL:webGL_hap_test", "windowStage:ActsWindowStageTest", "windowstandard:window_hap_test", #增加下面这行引入依赖 "libuv:ActsLibuvTestSuite", ] } else { deps = [ "appaccount:appaccount_hap", "osaccount:osaccount_hap", ] } }
同**《#跟着小白一起学鸿蒙# [一]运行OpenHarmony》**一样,在鸿蒙代码根目录执行以下命令:
./build.sh --product-name rk3568 --gn-args build_xts=true --build-target "acts" --gn-args is_standard_system=true
深入技巧:我们会发现每次编译都会消耗大量时间,这里我们浅论下鸿蒙的编译方式。
- build.sh: 源码路径下的编译脚本,其主要目标就是找vender目录和productdefine目录下对应的编译目标,然后对其目标进行gn编译
- gn编译:根据目标的build.gn文件生成build.ninja文件,总的build.ninja位于out/product目录下
- ninja:根据目标的build.ninja编译生成产出问题件
总结:所以如果不改动gn文件,但是改动源文件或者头文件的情况下,我们可以不用build.sh脚本生成代码,而是直接用ninja命令进行编译,如 ninja -C out/rk3568 uv_static
4.执行测试套件
同**《#跟着小白一起学鸿蒙# [一]运行OpenHarmony》**一样,在鸿蒙代码根目录/out/rk3568/suites/acts执行以下命令:
//此命令的前提是: //1, 开发板和上位机进行建立连接,没有配置网络的时候建议usb连接 //上位机执行:hdc_std shell (此命令可以进入开发板的shell,进行后续命令输入) //2, 开发板的hdcd服务配置完协议类型和端口 //板上执行:param set persist.hdc.mode all //板上执行:param set persist.hdc.port 10178 //板上执行:pkill hdcd (用来重启hdcd以便使用新配置) //3, 开发板配置ip地址,并确认网络 //板上查看ip地址命令:ifconfig //如果没有eth0则需要执行: ifconfig eth0 up //如果有eth0则可以配置ip地址:ifconfig eth0 192.168.137.105 //检验网络是否通畅:ping 上位机IP地址 python -m xdevice #run -l ActsLibuvTestSuite
5.查看测试套件执行结果
在鸿蒙代码根目录/out/rk3568/suites/acts/reports内可以看到最新时间戳的目录即为刚才运行的测试记录
. ├── 2022-08-16-14-15-25.zip ├── details_report.html //详细测试用例 ├── log │ ├── device_hilog_192.168.137.105_10178.log //系统hilog日志 │ └── task_log.log //测试用例输出日志 ├── result │ └── ActsLibuvTestSuite.xml //测试结果汇总 ├── summary.ini ├── summary_report.hash ├── summary_report.html //测试报告大纲 ├── summary_report.xml └── task_info.record
- 测试报告
- 测试报告详情
更多原创内容请关注:深开鸿Kaihong
入门到精通、技巧到案例,系统化分享OpenHarmony开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
贴一下前两篇的文章的链接:
#跟着小白一起学鸿蒙# [一]运行OpenHarmony
#跟着小白一起学鸿蒙# [二]第一个OpenHarmony程序
整个框架讲的很清楚
好的程序必然会有成熟的测试体系
感谢整理
不过现在有的项目往往测试不充分,把问题带到线上