鸿蒙5.0开发【黑盒覆盖率测试】测试框架

打印 上一主题 下一主题

主题 823|帖子 823|积分 2469

DevEco Studio支持黑盒覆盖率测试,不需要开发测试用例,将编译插桩的HAP包推到装备上,然后对该应用模拟用户操作,退出应用后即可生成覆盖率报告,当前仅支持Stage模子。

  • 将装备与电脑进行毗连,并对应用签名。
  • 实行hvigor插桩编译下令,编译后在{projectPath}/{moduleName}/.test/default/intermediates/ohosTest路径下会生成init_coverage.json文件,供后续生成覆盖率报告使用。
    1. hvigorw --mode module -p module={moduleName@productName} -p product={productName} -p buildMode=test -p ohos-test-coverage=true -p coverage-mode=black assembleHap --parallel --incremental --daemon
    复制代码

    • moduleName:实行测试的模块。
    • productName:当前生效的product,可以通过点击DevEco Studio右上方图标进行查看。

  • 如果装备上已存在待测试的应用,先卸载应用,不存在则跳过此步调:
    1. hdc uninstall {bundleName}
    复制代码

    • bundleName:装备上已安装的应用包名。

  • 将插桩编译生成的HAP包安装到装备上:
    1. hdc install {SignedHapPath}
    复制代码

    • SignedHapPath:已签名的HAP包路径,默认在模块的build\default\outputs\default目次下。

  • 在装备上模拟用户操作,进行黑盒测试,测试完毕后,退出应用。
  • 从装备上取出覆盖率数据json文件存放到电脑本地:
    1. hdc file recv data/app/el2/100/base/{bundleName}/haps/{moduleName}/cache {LocalPath}
    复制代码

    • LocalPath:数据在电脑本地存放的路径,默认存放在当前实行下令的目次。
    阐明
    在多模块相互跳转的场景下,只需要取最后退出的模块下生成的覆盖率数据json文件,但特别场景下如多模块无跳转关系,则需要取每个独立模块下生成的覆盖率数据json文件。

  • 生成覆盖率报告:
    1. hvigorw collectCoverage -p projectPath={projectPath} -p reportPath={reportPath} -p coverageFile={projectPath}/{moduleName}/.test/default/intermediates/ohosTest/init_coverage.json#{黑盒覆盖率文件保存路径}
    复制代码

    • projectPath:工程路径。
    • reportPath:指定的覆盖率报告文件生成路径。
    • 黑盒覆盖率文件生存路径:可以恣意指定,该路径用于拷贝上一个步调取出的覆盖率数据,可以是目次或json文件。
    阐明
    在多模块相互跳转的场景下,需要取各模块的init_coverage.json文件路径,与黑盒覆盖率文件生存路径通过#拼接生成coverageFile参数。

  • 在本地找到报告文件路径并在浏览器中打开,查看代码覆盖率详情9)。

查看覆盖率报告

测试覆盖率报告有四个测量维度,分别是:


  • 语句覆盖率(Statements):每个语句是否都已实行。
  • 分支覆盖率(Branches):每个流程控制的各个分支是否都已实行。
  • 函数覆盖率(Functions):每个函数是否都已调用。
  

  • 行覆盖率(Lines):每个可实行代码行是否都已实行。

以下是关于四个测量维度的细节阐明:


  • 流程控制
    常见的流程控制语句有if、while、do…while、switch、for等等,以及三目运算符(condition ? exprIfTrue : exprIfFalse),需要确保流程控制的每个界限情况(即分支)都被实行。
  

  • 行(Lines of Source Code) vs 可实行代码行(Lines of Executable Code)

    • “行覆盖率”中的行是指可实行代码行(Lines of Executable Code),而不是源文件中全部的行(含空行)(Lines of Source Code)。一样平常来说,包含语句的每一行都应被视为可实行行,而复合语句(简称为语句块,用 {} 括起来)会被忽略,但其内容除外。如下所示非可实行行标记为+0:

  1. function doTheThing ()  // +0
  2. {                       // +0
  3.     const num = 1;      // +1
  4.     console.log(num);   // +1
  5. }                       // +0
复制代码


  • 对于DevEco Studio的覆盖率测试引擎来说:
  • import、声明语句都被视为非可实行行(+0),赋值等语句视为可实行行(+1)。
  • 如果某行存在可实行代码,则这一整行会被视为可实行代码行(+1)。
  • 如果一个语句被拆分为多行,则该可实行代码块中,仅第一行被会视为可实行行。
  • 如果某行只包含标点符号 }});; ,会被视为非可实行行(+0)。
  • 如果某行只定义方法名,会被视为非可实行行(+0)。
  • 不管嵌套语句高出多少行,可实行行的数目仅会 +1。
示例如下:
  1. import { window } from '@kit.ArkUI';  // +0    import导入
  2. const path = 'path';
  3. let filePath :string;               // +0
  4. const fileName = 'a.txt';     // +1   不仅是声明,还有赋值
  5. export function doTheThing ()  // +0
  6. {                       // +0
  7.   const str = 'aaa';      // +1
  8.   console.log(str);   // +1
  9. }
  10. class Person {                // +0
  11.   name: string = ''           // +1
  12.   constructor (n:string) {      // +0
  13.     this.name = n;             // +1
  14.   }                         // +0
  15.   static sayHello () {      // +0
  16.     console.log('hello'); // +1
  17.   }                         // +0
  18.   walk () {}                // +0
  19. }
  20. let person = new Person("zhangsan");
  21. Person.sayHello();
  22. person.walk();
  23. 'use strict';
  24. for         // +1
  25. (         // +0
  26.   let i=0; // +1
  27.   i < 10;  // +0
  28.   i++      // +0
  29. )         // +0
  30. {           // +0
  31. }           // +0
  32. function func ():object {  // +0
  33.   return Object({        // +1      一个语句被拆分为多行
  34.     a: 1,       // +0
  35.     b: 2,       // +0
  36.   })              // +0
  37. }                   // +0
  38. func();
  39. function  foo(n:number, m:number){}    // +0
  40. function  bar():number{                // +0
  41.   return 1;   // +1
  42. }
  43. foo(1, bar());  // +1
  44. foo(1,       // +1      嵌套语句横跨多行  可执行行的数目仅+1
  45.   bar());  // +0
复制代码


  • 可实行代码行 vs 语句
    一样平常情况下,如果我们服从良好的代码规范,可实行代码行和语句的表现是划一的。然而当我们将两个语句放一行时,就会得到不同的结果。如下所示,第一段代码是2 lines、2 statements,第二段代码是1 line、2 statements。
  1. // 2 lines、2 statements
  2. const x = 1;
  3. console.log(x);
  4. // 1 line、2 statements
  5. const x = 1; console.log(x);
复制代码


  • 测试覆盖率报告的其他标识

    • E:‘else path not taken’,表现 if/else 语句的 if(含 else if)分支已测试,而 else 分支未测试。
    • I:‘if path not taken’,与上面的 ‘E’ 相反,即 if(含 else if) 分支未测试。
    • Nx:表现当前可实行代码行被实行了N次。
    • 粉色(背景色):语句/函数未覆盖。
    • 黄色(背景色):分支未覆盖。


  • 通过注释语法忽略指定代码
    代码中的某些分支可能很难、乃至无法测试,Deveco Studio提供了instrument ignore * 语法来进行忽略,使得某些代码不计入覆盖率。

    • 忽略文件: 在源文件中加入注释 // instrument ignore file或者 /* instrument ignore file */,加入注释后,该文件不再插桩,覆盖率报告也不会有该文件(请注意将项目中的.test和build文件夹删除,再进行覆盖率测试)。
    • 忽略代码块、class、function等: 在代码块前加入@Concurrent,/* instrument ignore next */,或者// instrument ignore next即可忽略。
    • 忽略if/else分支: 在条件表达式前加上// instrument ignore if或者/* instrument ignore if*/(忽略if),// instrument ignore else或者/* instrument ignore else*/(忽略else)。

  1. import {testA} from './Index'
  2. /* instrument ignore file */   忽略整个文件
  3. // instrument ignore next       忽略代码块
  4. export function sum(a:number,b:number){
  5.   return a+b;
  6. }
  7. sum(1,2);
  8. let a = 1;
  9. /* instrument ignore else */    忽略else分支
  10. if (a!=1) {
  11.   // do something
  12.   console.log('BBB');
  13. }else {
  14.   console.log('AAA');
  15. }
  16. /* instrument ignore if */    忽略if分支
  17. if (a==1) {
  18.   // do something
  19.   console.log('BBB');
  20. }else {
  21.   console.log('AAA');
  22. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用多少眼泪才能让你相信

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表