#跟着小白一起学鸿蒙# [三]手写一个测试用例 原创 精华

深开鸿
发布于 2022-9-13 10:43
浏览
3收藏

作者:王石,胡瑞涛

开源鸿蒙测试初识

在**《#跟着小白一起学鸿蒙# [一]运行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						//测试套件执行配置
  • 测试套件编译脚本-BUILD.gn

    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是鸿蒙的主要编译文件,以脚本的方式提供以下主要几种编译方式:
    1. ohos_static_library(“静态库名称”)
    2. ohos_shared_library(“动态库名称”)
    3. ohos_ndk_library(“ndk名称”)
    4. ohos_executable(“可执行文件名称”)
    5. ohos_moduletest_suite(“模块测试suite名称”)
    6. ohos_hap_suite(“hap测试suite名称”)
    7. ohos_js_hap_suite(“js测试suite名称”)
    8. ohos_shell_app_suite(“脚本测试suite名称”)
    9. 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");
        }
    }
    
    1. 我们选取的此测试套件是模块测试套件,所以使用gtest测试框架进行测试
    2. gtest测试框架采用TestSuite + TestCase的组成方式,所以我们定义了ActsLibuvTestSuite作为测试Suite,然后添加两个testLibuvTestCase001,testLibuvTestCase002作为测试Case
    3. 判断一个测试是否通过可以用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”: 执行测试套件前需要配置的命令

    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
    

    深入技巧:我们会发现每次编译都会消耗大量时间,这里我们浅论下鸿蒙的编译方式。

    1. build.sh: 源码路径下的编译脚本,其主要目标就是找vender目录和productdefine目录下对应的编译目标,然后对其目标进行gn编译
    2. gn编译:根据目标的build.gn文件生成build.ninja文件,总的build.ninja位于out/product目录下
    3. 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开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
6
收藏 3
回复
举报
5条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋
回复
2022-9-13 10:50:13
冰淇淋爱我
冰淇淋爱我

整个框架讲的很清楚

回复
2022-9-13 14:31:18
0aaron
0aaron

好的程序必然会有成熟的测试体系

回复
2022-9-15 11:34:03
麻辣香锅配馒头
麻辣香锅配馒头 回复了 红叶亦知秋
贴一下前两篇的文章的链接: #跟着小白一起学鸿蒙# [一]运行OpenHarmony #跟着小白一起学鸿蒙# [二]第一个OpenHarmony程序

感谢整理

回复
2022-9-15 15:49:43
真庐山升龙霸
真庐山升龙霸 回复了 0aaron
好的程序必然会有成熟的测试体系

不过现在有的项目往往测试不充分,把问题带到线上

回复
2022-9-16 10:43:27
回复
    相关推荐