文档管理中心
工具开发工具DevEco Studio(Windows/macOS版)编写与调试应用开发自测试测试框架黑盒覆盖率测试

黑盒覆盖率测试

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

使用约束

  • DevEco Studio 6.0.1 Beta1版本前,仅支持对UIAbility进行覆盖率测试。
  • 从DevEco Studio 6.0.1 Beta1版本开始,当继承的ExtensionAbility中存在onDump或onDestroy方法时,支持获取覆盖率数据。如果两个方法都不存在,则无法进行覆盖率测试。
  • 覆盖率测试不支持开启混淆。

前置操作

将设备与电脑进行连接,并对应用/元服务签名,具体请参考使用本地真机运行应用和应用/元服务签名。

配置覆盖率过滤文件

从DevEco Studio 5.1.0 Release版本开始,支持自定义参与覆盖率测试的文件。在工程目录下创建coverage-filter.json5文件,在文件中配置相关字段,DevEco Studio编译插桩时将按照coverage-filter.json5文件中的配置进行过滤。

说明

修改配置文件后不会触发增量编译,需要重新编译插桩再测试。

coverage-filter.json5文件字段说明

coverage-filter.json5文件支持以下字段。

展开

字段名称

可选/必选

类型

适用的覆盖率测试

含义

include

可选

字符串数组

黑盒覆盖率测试

仪器覆盖率测试

本地覆盖率测试

配置参与覆盖率测试的文件或文件夹路径。

  • 26.0.0及以上版本:字段可选,路径配置支持以下通配符。
    • *:匹配文件名中的任意数量字符。
    • **:匹配任意文件夹。
    • ?:匹配文件名的单个字符。
  • 26.0.0以下版本:字段必选,仅支持模块名开头的路径,不支持通配符。
说明

include的优先级比exclude高。

exclude

可选

字符串数组

黑盒覆盖率测试

仪器覆盖率测试

本地覆盖率测试

配置不参与覆盖率测试的文件或文件夹路径。

  • 26.0.0及以上版本:字段可选,路径配置支持通配符,支持的通配符和include字段相同。
  • 26.0.0以下版本:字段必选,仅支持模块名开头的路径,不支持通配符。

includeHar

可选

字符串数组

黑盒覆盖率测试

仪器覆盖率测试

本地覆盖率测试

配置参与覆盖率测试的远程源码har包,不支持远程字节码har包,不支持通配符。

从26.0.0版本开始支持。

extraAbilities

可选

对象数组

黑盒覆盖率测试

如果module.json5中配置的ability是通过import外部的ability类实现,同时在当前文件通过export导出,此ability无法生成黑盒覆盖率数据。可配置extraAbilities>path字段,填写外部的ability路径,生成黑盒覆盖率数据。支持相对路径,不支持通配符。示例如下。

从26.0.0版本开始支持。

extraAbilities字段示例:

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. import EntryAbility from './EntryAbility';
  3. export default EntryAbility;
  4. // coverage-filter.json5
  5. {
  6. "extraAbilities": [
  7. {
  8. "path": "entry/src/main/ets/entryability/EntryAbility.ets", // import的EntryAbility的相对路径
  9. },
  10. ],
  11. }

coverage-filter.json5文件示例

收起
自动换行
深色代码主题
复制
  1. // 26.0.0及以上版本
  2. {
  3. "include":[
  4. "entry/src/main/ets/pages" // 无通配符,包括pages下所有文件
  5. ],
  6. "exclude":[
  7. "**/src/**/HspTest?.ets", // src目录下的HspTest1.ets、HspTest2.ets等文件
  8. "**/src/**/*Test1.*", // src目录下所有文件名中有Test1.的文件
  9. "**/src/**/utils" // src目录底下所有utils文件夹里的文件
  10. ],
  11. "includeHar":[
  12. "math"
  13. ],
  14. "extraAbilities": [
  15. {
  16. "path": "entry/src/main/ets/entryability/EntryAbility.ets"
  17. }
  18. ]
  19. }
  20. // 26.0.0以下版本
  21. {
  22. "include":[
  23. "entry/src/main/ets/pages/aaa.ets"
  24. ],
  25. "exclude":[
  26. "entry/src/main/ets/pages"
  27. ]
  28. }

执行覆盖率测试

编译与安装

有两种方式进行编译与安装,DevEco Studio方式和命令行方式,具体步骤如下。

  • 方式一:通过DevEco Studio进行编译与安装,从DevEco Studio 6.0.2 Beta1版本开始支持。
    1. 点击菜单栏Run > Edit Configurations > Diagnostics,勾选Black Coverage,开启黑盒覆盖率测试。
      说明
      • 调试场景下,该配置不生效,运行的是未插桩的应用。
      • attach调试和等待调试场景下,该配置会导致断点不准确,建议取消该配置。

    2. 点击工具栏,DevEco Studio会启动编译插桩,并推包安装到设备上。
  • 方式二:通过命令行进行编译与安装
    1. 执行hvigor插桩编译命令,编译后在{projectPath}/{moduleName}/.test/default/intermediates/ohosTest路径下会生成init_coverage.json文件,供后续生成覆盖率报告使用。
      收起
      自动换行
      深色代码主题
      复制
      1. hvigorw --mode module -p module={moduleName@targetName} -p product={productName} -p buildMode=test -p ohos-test-coverage=true -p coverage-mode=black assembleHap --parallel --incremental --daemon
      • moduleName:执行测试的模块。
      • targetName/productName:当前生效的target/product,可以通过点击DevEco Studio右上方图标进行查看。
      说明

      如果HAP依赖HSP,需要单独编译HSP,将以上命令的assembleHap替换为assembleHsp即可。

    2. 如果设备上已存在待测试的应用,先卸载应用,不存在则跳过此步骤,关于hdc工具的使用指导请参考hdc。
      收起
      自动换行
      深色代码主题
      复制
      1. hdc uninstall {bundleName}
      • bundleName:设备上已安装的应用包名。
    3. 将插桩编译生成的HAP包安装到设备上,如果依赖HSP,需要同时安装HSP。
      收起
      自动换行
      深色代码主题
      复制
      1. hdc install {SignedHapPath}
      • SignedHapPath:已签名的HAP包路径,默认在模块的build\{productName}\outputs\{targetName}目录下。

进行测试

在设备上模拟用户操作,进行黑盒测试,测试完毕后,通过以下方式,生成覆盖率数据。
  • 针对UIAbility和存在onDump方法的ExtensionAbility,执行命令生成覆盖率数据。UIAbility从DevEco Studio 5.1.0 Release版本开始支持,ExtensionAbility从DevEco Studio 6.0.1 Beta1版本开始支持。
    收起
    自动换行
    深色代码主题
    复制
    1. hdc shell aa dump -c -l
  • 针对UIAbility,退出应用,触发onDestroy()回调,生成覆盖率数据。
  • 针对存在onDestroy方法的ExtensionAbility,Ability销毁时,触发onDestroy()回调,生成覆盖率数据。从DevEco Studio 6.0.1 Beta1版本开始支持。
  • 针对UIAbility,支持通过EventHub接口通知UIAbility生成覆盖率数据。从DevEco Studio 6.0.2 Beta1版本开始支持。
    收起
    自动换行
    深色代码主题
    复制
    1. const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
    2. context.eventHub.emit('coverage');
说明

从API 13开始,如果用户使用最近任务列表一键清理来关闭应用,将不会执行onDestroy()回调,导致获取不到覆盖率数据。

生成覆盖率报告

  1. 从设备上取出覆盖率数据json文件存放到电脑本地,该命令会将cache目录下的所有文件都保存到LocalPath目录下。
    收起
    自动换行
    深色代码主题
    复制
    1. // 如果是应用则执行该命令,其中LocalPath非必填,如果不填写,默认存放在当前执行命令的目录
    2. hdc file recv data/app/el2/100/base/{bundleName}/haps/{moduleName}/cache {LocalPath}
    3. // 如果是元服务则执行该命令,其中LocalPath必填
    4. hdc file recv -b {bundleName} ls ./data/storage/el2/base/haps/{moduleName}/cache {LocalPath}
    • LocalPath:数据在电脑本地存放的路径。
    说明

    在多模块相互跳转的场景下,只需要取最后退出的模块下生成的覆盖率数据json文件,但特殊场景下如多模块无跳转关系,则需要取每个独立模块下生成的覆盖率数据json文件。

  2. 生成覆盖率报告:
    收起
    自动换行
    深色代码主题
    复制
    1. hvigorw collectCoverage -p projectPath={projectPath} -p reportPath={reportPath} -p coverageFile={projectPath}/{moduleName}/.test/default/intermediates/ohosTest/init_coverage.json#{LocalPath/bjc_cov_yyyyMMdd_HHmmss_SSS.json} -p patch={patchPath}
    • projectPath:工程路径。
    • reportPath:指定的覆盖率报告文件生成路径。
    • bjc_cov_yyyyMMdd_HHmmss_SSS.json:指定上一个步骤LocalPath目录下的一份最新的json文件,格式以bjc_cov开头,yyyyMMdd_HHmmss_SSS表示年月日_时分秒_毫秒。
    • patchPath:可选参数,指定代码补丁文件路径,用于统计增量代码覆盖率。仅支持绝对路径,后缀必须为.patch或.diff,可以通过git diff等命令生成。从26.0.0版本开始支持。
    说明

    在多模块相互跳转的场景下,需要取各模块的init_coverage.json文件路径,与bjc_cov_yyyyMMdd_HHmmss_SSS.json文件通过#拼接生成coverageFile参数。

  3. 在本地找到报告文件路径并在浏览器中打开,查看代码覆盖率详情,关于覆盖率的计算方式请参考查看覆盖率报告。

查看覆盖率报告

执行覆盖率测试后,会生成两份报告,一份是html格式,用于可视化查看报告,一份是json格式,即coverageReport.json文件,记录了详细的覆盖率数据,文件中各字段的含义请参考覆盖率coverageReport.json文件。

覆盖率报告解读

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

  • 函数覆盖率(Functions):每个函数是否都已调用。
  • 分支覆盖率(Branches):每个流程控制的各个分支是否都已执行。
  • 行覆盖率(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)。一般来说,包含语句的每一行都应被视为可执行行。
    • 对于DevEco Studio的覆盖率测试引擎来说,只会统计方法内的语句,方法外的语句都不会被统计覆盖率。
      • 方法内,如果某行存在可执行代码,则这一整行会被视为可执行代码行(+1)。
      • 方法内,如果某行只包含标点符号{,会被视为可执行行(+1)。
      • 方法内,如果某行只包含标点符号}、}) 或 }); ,会被视为非可执行行(+0)。
      说明

      箭头函数在方法内时,可以正常统计覆盖率,如果作为参数声明,则无法统计该行覆盖率。

      示例如下:

      收起
      自动换行
      深色代码主题
      复制
      1. import { window } from '@kit.ArkUI'; // +0 方法外不统计
      2. let filePath :string; // +0 方法外不统计
      3. const fileName = 'a.txt'; // +0 方法外不统计
      4. export function doTheThing () // +1
      5. { // +1
      6. let s1: string; // +1
      7. const str = 'aaa'; // +1
      8. console.log(str); // +1
      9. } // +0
      10. export class Person { // +0 方法外不统计
      11. name: string = '' // +0 方法外不统计
      12. constructor (n:string) { // +1 构造函数
      13. this.name = n; // +1
      14. } // +0
      15. static sayHello () { // +1 类静态方法
      16. console.log('hello'); // +1
      17. } // +0
      18. walk () { // +1 类实例方法
      19. for ( // +1
      20. let i=0; // +1
      21. i < 10; // +1
      22. i++) // +1
      23. { // +1
      24. } // +0
      25. } // +0
      26. } // +0
      27. function func ():object { // +1
      28. return Object({ // +1 一个语句被拆分为多行
      29. a: 1, // +1
      30. b: 2, // +1
      31. }) // +0
      32. } // +0
      33. func(); // +0 方法外不统计
      34. function foo(n:number, m:number){} // +1
      35. function bar():number { // +1
      36. return 1; // +1
      37. }
      38. foo(1, bar()); // +0 方法外不统计
  • 测试覆盖率报告左侧的标识:
    • 灰色:不统计覆盖率。
    • 粉色:语句/函数未覆盖。
    • 绿色:语句/函数覆盖。
    • Nx:表示当前可执行代码行被执行了N次。

  • 通过注释语法忽略指定代码

    代码中的某些分支可能很难、甚至无法测试,DevEco Studio提供了instrument ignore * 语法来进行忽略,使得某些代码不计入覆盖率。

    说明

    使用时需先清除缓存,点击菜单栏Build -> Clean Project。

    • 忽略文件:在源文件中加入注释 // instrument ignore file或者 /* instrument ignore file */,加入注释后,该文件不再插桩,覆盖率报告也不会有该文件。
    • 忽略代码块、class、function等:在代码块前加入/* 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. }

覆盖率coverageReport.json文件

覆盖率coverageReport.json文件记录了详细的覆盖率数据,文件中各字段的含义如下。

在阅读本文前,请先查看覆盖率报告解读,了解行覆盖率、分支覆盖率和函数覆盖率的相关概念和统计方式。

  1. summary字段记录了本次测试的覆盖率,包括行覆盖率、函数覆盖率和分支覆盖率,示例如下。
    收起
    自动换行
    深色代码主题
    复制
    1. {
    2. "summary": {
    3. "lines": { // 行数总览
    4. "total": 43, // 可执行行代码行数
    5. "covered": 12, // 覆盖数量
    6. "pct": 27.91 // 行覆盖率
    7. },
    8. "functions": { // 函数总览
    9. "total": 17, // 函数数量
    10. "covered": 4, // 覆盖数量
    11. "pct": 23.53 // 函数覆盖率
    12. },
    13. "branches": { // 分支总览
    14. "total": 2, // 分支数量
    15. "covered": 0, // 覆盖数量
    16. "pct": 0 // 分支覆盖率
    17. }
    18. },
    19. }
  2. files是个数组,记录了所有文件的详细覆盖率数据,数组中的每个元素对应一个文件。
    以一个文件为例,各字段含义如下。
    收起
    自动换行
    深色代码主题
    复制
    1. {
    2. "files": [
    3. {
    4. "version": "bjc v1.0.0", // 覆盖率算法版本
    5. "versionCode": 10000, // 覆盖率算法版本代码
    6. "path": "D:/DevEcoStudioProjects/MyApplication36/application/src/main/ets/applicationability/ApplicationAbility.ets", // 文件路径
    7. "hash": "6828362e96a78934b93db4b980fa5ad83af85a111bf187e74da89ae0c0ec613a", // 文件内容hash值
    8. "lineCnt": 44, // 当前文件总行数
    9. "count": 0, // 执行次数
    10. "projectPath": "D:/DevEcoStudioProjects/MyApplication36", // 工程路径
    11. "functions": [], // 函数集合
    12. "exeLine": {}, // 可执行代码行
    13. "summary": {} // 单个文件的覆盖率详情
    14. },
    15. ]
    16. }
  • functions

    functions是个数组,记录了文件中所有函数的详细覆盖率数据,数组中的每个元素对应一个函数。

    收起
    自动换行
    深色代码主题
    复制
    1. "functions": [
    2. {
    3. "name": "ApplicationAbility.onCreate", // 函数名称,如果是匿名函数,name是anonymous_N
    4. "count": 0, // 函数执行次数
    5. "regions": [], // 对应代码区域
    6. "branches": [], // 分支
    7. "ignored": 0, // 函数忽略次数
    8. "index": 0 // 函数在整个文件中的位置,从0开始排序
    9. },
    10. ]
    • regions

      regions是一个可执行行数组,数组可能有一个元素、两个元素或多个元素。

      第一个元素是该方法对应的代码区域,如果不止一个元素,后面的元素是方法内的可执行代码区域。元素中每个字段的含义如下。

      收起
      自动换行
      深色代码主题
      复制
      1. "regions": [
      2. {
      3. "startLoc": { // 开始代码位置
      4. "line": 8, // 起始行号
      5. "col": 3 // 起始列号
      6. },
      7. "endLoc": { // 结束代码位置
      8. "line": 10, // 结束行号
      9. "col": 4 // 结束列号
      10. },
      11. "count": 0, // 执行次数
      12. "ignored": 0 // 忽略次数
      13. }
      14. ]
      • 如果方法内没有任何实现,是个空方法,则regions数组只有一个元素,即方法对应的代码区域,示例如下。

        收起
        自动换行
        深色代码主题
        复制
        1. {
        2. "name": "dddd",
        3. "count": 1,
        4. "regions": [
        5. {
        6. "startLoc": {
        7. "line": 31,
        8. "col": 1
        9. },
        10. "endLoc": {
        11. "line": 33,
        12. "col": 2
        13. },
        14. "count": 1,
        15. "ignored": 0
        16. }
        17. ],
        18. },
      • 如果方法内只有一个代码区域,则regions数组有两个元素,示例如下。

        收起
        自动换行
        深色代码主题
        复制
        1. {
        2. "name": "aaaaa",
        3. "count": 2,
        4. "regions": [
        5. { // 方法对应的代码区域
        6. "startLoc": {
        7. "line": 2,
        8. "col": 1
        9. },
        10. "endLoc": {
        11. "line": 9,
        12. "col": 2
        13. },
        14. "count": 2,
        15. "ignored": 0
        16. },
        17. { // 可执行代码区域
        18. "startLoc": {
        19. "line": 4,
        20. "col": 3
        21. },
        22. "endLoc": {
        23. "line": 9,
        24. "col": 2
        25. },
        26. "count": 2,
        27. "ignored": 0
        28. }
        29. ],
        30. }
      • 如果方法内存在多个代码区域,则每新增一个代码区域,regions数组就增加一个元素,示例如下。

        收起
        自动换行
        深色代码主题
        复制
        1. {
        2. "name": "bbb",
        3. "count": 1,
        4. "regions": [
        5. { // 方法对应的代码区域11-18行
        6. "startLoc": {
        7. "line": 11,
        8. "col": 1
        9. },
        10. "endLoc": {
        11. "line": 18,
        12. "col": 2
        13. },
        14. "count": 1,
        15. "ignored": 0
        16. },
        17. { // 第一个可执行代码区域13-15行
        18. "startLoc": {
        19. "line": 13,
        20. "col": 13
        21. },
        22. "endLoc": {
        23. "line": 15,
        24. "col": 4
        25. },
        26. "count": 0, // 由于flag是false,代码未执行
        27. "ignored": 0
        28. },
        29. { // 第二个可执行代码区域15-17行
        30. "startLoc": {
        31. "line": 15,
        32. "col": 10
        33. },
        34. "endLoc": {
        35. "line": 17,
        36. "col": 4
        37. },
        38. "count": 1, // 代码被执行
        39. "ignored": 0
        40. }
        41. ],
        42. }
    • branches

      branches是个分支数组,会将if和switch case这种条件判断语句相关的代码块放入数组中,数组中每个元素的字段含义如下。

      收起
      自动换行
      深色代码主题
      复制
      1. "branches": [
      2. {
      3. "startLoc": { // 开始代码位置
      4. "line": 46, // 起始行号
      5. "col": 10 // 起始列号
      6. },
      7. "endLoc": { // 结束代码位置
      8. "line": 46, // 结束行号
      9. "col": 11 // 结束列号
      10. },
      11. "trueCount": 0, // 该行满足条件的已执行次数,0表示未执行
      12. "falseCount": 1, // 该行不满足条件的已执行次数,0表示未执行
      13. "group": [ // 分组,if语句不涉及分组,switch case涉及分组
      14. 0, // group:[0,1],表示branches数组的0号和1号元素属于一个switch case
      15. 1
      16. ],
      17. "ignored": 0 // 忽略次数
      18. }
      19. ]

      示例一:调用eeee(2)。

      收起
      自动换行
      深色代码主题
      复制
      1. {
      2. "name": "eeee",
      3. "count": 1,
      4. "regions": [
      5. // ...
      6. ],
      7. "branches": [
      8. {
      9. "startLoc": {
      10. "line": 46,
      11. "col": 10
      12. },
      13. "endLoc": {
      14. "line": 46,
      15. "col": 11
      16. },
      17. "trueCount": 0, // 该行条件未执行
      18. "falseCount": 1, // 该行已执行,但不满足条件
      19. "group": [ // 0和1号元素属于1个switch case,2和3号元素属于另一个switch case
      20. 0,
      21. 1
      22. ],
      23. "ignored": 0
      24. },
      25. {
      26. "startLoc": {
      27. "line": 49,
      28. "col": 10
      29. },
      30. "endLoc": {
      31. "line": 49,
      32. "col": 11
      33. },
      34. "trueCount": 1,
      35. "falseCount": 0,
      36. "group": [
      37. 0,
      38. 1
      39. ],
      40. "ignored": 0
      41. },
      42. {
      43. "startLoc": {
      44. "line": 55,
      45. "col": 10
      46. },
      47. "endLoc": {
      48. "line": 55,
      49. "col": 13
      50. },
      51. "trueCount": 0,
      52. "falseCount": 1,
      53. "group": [
      54. 2,
      55. 3
      56. ],
      57. "ignored": 0
      58. },
      59. {
      60. "startLoc": {
      61. "line": 58,
      62. "col": 10
      63. },
      64. "endLoc": {
      65. "line": 58,
      66. "col": 13
      67. },
      68. "trueCount": 1,
      69. "falseCount": 0,
      70. "group": [
      71. 2,
      72. 3
      73. ],
      74. "ignored": 0
      75. }
      76. ],
      77. }

      示例二:调用bbb(2)和bbb(-1),该方法触发两次。

      branches的0号元素,对应12行,trueCount和falseCount都为1,表示该行触发了两次,一次满足条件,一次不满条件。

      收起
      自动换行
      深色代码主题
      复制
      1. {
      2. "name": "bbb",
      3. "count": 2,
      4. "regions": [
      5. // ...
      6. ],
      7. "branches": [
      8. {
      9. "startLoc": {
      10. "line": 12,
      11. "col": 7
      12. },
      13. "endLoc": {
      14. "line": 12,
      15. "col": 12
      16. },
      17. "trueCount": 1,
      18. "falseCount": 1,
      19. "group": [],
      20. "ignored": 0
      21. },
      22. {
      23. "startLoc": {
      24. "line": 14,
      25. "col": 14
      26. },
      27. "endLoc": {
      28. "line": 14,
      29. "col": 20
      30. },
      31. "trueCount": 0,
      32. "falseCount": 1,
      33. "group": [],
      34. "ignored": 0
      35. },
      36. {
      37. "startLoc": {
      38. "line": 22,
      39. "col": 7
      40. },
      41. "endLoc": {
      42. "line": 22,
      43. "col": 13
      44. },
      45. "trueCount": 1,
      46. "falseCount": 1,
      47. "group": [],
      48. "ignored": 0
      49. }
      50. ]
      51. }
  • exeLine

    exeLine记录了所有可执行行的行号,示例如下。

    生成的exeLine为:

    收起
    自动换行
    深色代码主题
    复制
    1. "exeLine": {
    2. "0": 2,
    3. "1": 3,
    4. "2": 4,
    5. "3": 6,
    6. "4": 7,
    7. "5": 8,
    8. }
  • summary

    summary记录了单个文件的覆盖率详情。

    收起
    自动换行
    深色代码主题
    复制
    1. "summary": {
    2. "lines": { // 行数总览
    3. "total": 10, // 可执行代码行数
    4. "covered": 5, // 覆盖数量
    5. "pct": 50, // 行覆盖率
    6. "executedLineCount": [ // 代码行执行次数,-1表示该行不被统计,0表示未执行,1-N表示执行1-N次
    7. -1,
    8. -1,
    9. -1,
    10. 0,
    11. -1,
    12. 1,
    13. 0,
    14. 2,
    15. 2,
    16. -1,
    17. 1,
    18. 1,
    19. 0,
    20. 0,
    21. 0,
    22. -1
    23. ]
    24. },
    25. "functions": { // 函数总览
    26. "total": 6, // 函数数量
    27. "covered": 5, // 覆盖数量
    28. "pct": 83.33 // 函数覆盖率
    29. },
    30. "branches": { // 分支总览
    31. "total": 2, // 分支数量
    32. "covered": 1, // 覆盖数量
    33. "pct": 50 // 分支覆盖率
    34. }
    35. }