鸿蒙5.0开发【黑盒覆盖率测试】测试框架
DevEco Studio支持黑盒覆盖率测试,不需要开发测试用例,将编译插桩的HAP包推到装备上,然后对该应用模拟用户操作,退出应用后即可生成覆盖率报告,当前仅支持Stage模子。[*] 将装备与电脑进行毗连,并对应用签名。
[*] 实行hvigor插桩编译下令,编译后在{projectPath}/{moduleName}/.test/default/intermediates/ohosTest路径下会生成init_coverage.json文件,供后续生成覆盖率报告使用。
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右上方图标进行查看。
[*] 如果装备上已存在待测试的应用,先卸载应用,不存在则跳过此步调:
hdc uninstall {bundleName}
[*]bundleName:装备上已安装的应用包名。
[*] 将插桩编译生成的HAP包安装到装备上:
hdc install {SignedHapPath}
[*]SignedHapPath:已签名的HAP包路径,默认在模块的build\default\outputs\default目次下。
[*] 在装备上模拟用户操作,进行黑盒测试,测试完毕后,退出应用。
[*] 从装备上取出覆盖率数据json文件存放到电脑本地:
hdc file recv data/app/el2/100/base/{bundleName}/haps/{moduleName}/cache {LocalPath}
[*]LocalPath:数据在电脑本地存放的路径,默认存放在当前实行下令的目次。
阐明
在多模块相互跳转的场景下,只需要取最后退出的模块下生成的覆盖率数据json文件,但特别场景下如多模块无跳转关系,则需要取每个独立模块下生成的覆盖率数据json文件。
[*] 生成覆盖率报告:
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)。
https://i-blog.csdnimg.cn/direct/9a462a4b988742a4a5474fbcf56d3fb2.png
查看覆盖率报告
测试覆盖率报告有四个测量维度,分别是:
[*]语句覆盖率(Statements):每个语句是否都已实行。
[*]分支覆盖率(Branches):每个流程控制的各个分支是否都已实行。
[*]函数覆盖率(Functions):每个函数是否都已调用。
[*]行覆盖率(Lines):每个可实行代码行是否都已实行。
https://i-blog.csdnimg.cn/direct/31981348ad304e17a47993ae8b32b969.png
以下是关于四个测量维度的细节阐明:
[*] 流程控制
常见的流程控制语句有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:
function doTheThing ()// +0
{ // +0
const num = 1; // +1
console.log(num); // +1
} // +0
[*] 对于DevEco Studio的覆盖率测试引擎来说:
[*] import、声明语句都被视为非可实行行(+0),赋值等语句视为可实行行(+1)。
[*] 如果某行存在可实行代码,则这一整行会被视为可实行代码行(+1)。
[*] 如果一个语句被拆分为多行,则该可实行代码块中,仅第一行被会视为可实行行。
[*] 如果某行只包含标点符号 } 、 }); 或 ; ,会被视为非可实行行(+0)。
[*] 如果某行只定义方法名,会被视为非可实行行(+0)。
[*] 不管嵌套语句高出多少行,可实行行的数目仅会 +1。
示例如下:
import { window } from '@kit.ArkUI';// +0 import导入
const path = 'path';
let filePath :string; // +0
const fileName = 'a.txt'; // +1 不仅是声明,还有赋值
export function doTheThing ()// +0
{ // +0
const str = 'aaa'; // +1
console.log(str); // +1
}
class Person { // +0
name: string = '' // +1
constructor (n:string) { // +0
this.name = n; // +1
} // +0
static sayHello () { // +0
console.log('hello'); // +1
} // +0
walk () {} // +0
}
let person = new Person("zhangsan");
Person.sayHello();
person.walk();
'use strict';
for // +1
( // +0
let i=0; // +1
i < 10;// +0
i++ // +0
) // +0
{ // +0
} // +0
function func ():object {// +0
return Object({ // +1 一个语句被拆分为多行
a: 1, // +0
b: 2, // +0
}) // +0
} // +0
func();
functionfoo(n:number, m:number){} // +0
functionbar():number{ // +0
return 1; // +1
}
foo(1, bar());// +1
foo(1, // +1 嵌套语句横跨多行可执行行的数目仅+1
bar());// +0
[*] 可实行代码行 vs 语句
一样平常情况下,如果我们服从良好的代码规范,可实行代码行和语句的表现是划一的。然而当我们将两个语句放一行时,就会得到不同的结果。如下所示,第一段代码是2 lines、2 statements,第二段代码是1 line、2 statements。
// 2 lines、2 statements
const x = 1;
console.log(x);
// 1 line、2 statements
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次。
[*]粉色(背景色):语句/函数未覆盖。
[*]黄色(背景色):分支未覆盖。
https://i-blog.csdnimg.cn/direct/ee8c199d47e14323a62e2d993fa8fb86.png
[*] 通过注释语法忽略指定代码
代码中的某些分支可能很难、乃至无法测试,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)。
import {testA} from './Index'
/* instrument ignore file */ 忽略整个文件
// instrument ignore next 忽略代码块
export function sum(a:number,b:number){
return a+b;
}
sum(1,2);
let a = 1;
/* instrument ignore else */ 忽略else分支
if (a!=1) {
// do something
console.log('BBB');
}else {
console.log('AAA');
}
/* instrument ignore if */ 忽略if分支
if (a==1) {
// do something
console.log('BBB');
}else {
console.log('AAA');
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]