我有一个Angular 项目,我想用内置的单元测试工具(Karma)和 cypress 来测试它.我的任务是将两者的code coverage reports合并.

我已成功创建覆盖配置.输出成功地与nyc merge合并:然而,这些数字并不相加.

package.json起的相关版本:

    "@angular/core": "^16.0.3",
    "cypress": "^12.13.0",
    "istanbul-lib-coverage": "^3.2.0",
    "@cypress/code-coverage": "^3.11.0",
    "@cypress/webpack-preprocessor": "^5.17.1",
    "@istanbuljs/nyc-config-typescript": "^1.0.2",
    "@jsdevtools/coverage-istanbul-loader": "^3.0.5",
    "karma": "^6.4.2",
    "karma-coverage": "^2.2.0",
    "nyc": "^15.1.0",

以下是Karma年度覆盖率报告结果中的一个文件示例:

...
".../frontend/src/main/resources/ngapp/src/app/common/app-components/language-selector/language-selector.component.ts": {"path":".../frontend/src/main/resources/ngapp/src/app/common/app-components/language-selector/language-selector.component.ts","statementMap":{"0":{"start":{"line":16,"column":11},"end":{"line":16,"column":38}},"1":{"start":{"line":17,"column":12},"end":{"line":17,"column":40}},"2":{"start":{"line":18,"column":21},"end":{"line":18,"column":45}},"3":{"start":{"line":19,"column":12},"end":{"line":19,"column":38}},"4":{"start":{"line":23,"column":4},"end":{"line":23,"column":56}},"5":{"start":{"line":27,"column":4},"end":{"line":27,"column":30}},"6":{"start":{"line":28,"column":4},"end":{"line":28,"column":35}},"7":{"start":{"line":29,"column":4},"end":{"line":29,"column":62}},"8":{"start":{"line":33,"column":4},"end":{"line":33,"column":39}},"9":{"start":{"line":37,"column":4},"end":{"line":37,"column":30}},"10":{"start":{"line":38,"column":4},"end":{"line":38,"column":31}},"11":{"start":{"line":11,"column":13},"end":{"line":40,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"loc":{"start":{"line":19,"column":38},"end":{"line":20,"column":6}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":22,"column":2},"end":{"line":22,"column":10}},"loc":{"start":{"line":22,"column":10},"end":{"line":24,"column":3}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":26,"column":2},"end":{"line":26,"column":16}},"loc":{"start":{"line":26,"column":22},"end":{"line":30,"column":3}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":32,"column":2},"end":{"line":32,"column":9}},"loc":{"start":{"line":32,"column":13},"end":{"line":34,"column":3}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":36,"column":2},"end":{"line":36,"column":18}},"loc":{"start":{"line":36,"column":18},"end":{"line":39,"column":3}}}},"branchMap":{},"s":{"0":11,"1":11,"2":11,"3":11,"4":7,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":1},"f":{"0":11,"1":7,"2":0,"3":0,"4":0},"b":{}}
...

The lcov-report of the Karma run: HTML report of the Karma run

coverage-final.json%的Cypress覆盖率结果中的相同文件:

...
".../frontend/src/main/resources/ngapp/src/app/common/app-components/language-selector/language-selector.component.ts": {"path":".../frontend/src/main/resources/ngapp/src/app/common/app-components/language-selector/language-selector.component.ts","statementMap":{"0":{"start":{"line":11,"column":38},"end":{"line":11,"column":null}},"1":{"start":{"line":19,"column":38},"end":{"line":19,"column":null}},"2":{"start":{"line":16,"column":11},"end":{"line":16,"column":38}},"3":{"start":{"line":17,"column":12},"end":{"line":17,"column":40}},"4":{"start":{"line":18,"column":21},"end":{"line":18,"column":45}},"5":{"start":{"line":19,"column":12},"end":{"line":19,"column":38}},"6":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"7":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"8":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"9":{"start":{"line":29,"column":4},"end":{"line":29,"column":null}},"10":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"11":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"12":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"13":{"start":{"line":11,"column":13},"end":{"line":11,"column":null}}},"fnMap":{"0":{"name":"(anonymous_1)","decl":{"start":{"line":11,"column":38},"end":{"line":11,"column":null}},"loc":{"start":{"line":11,"column":38},"end":{"line":11,"column":null}}},"1":{"name":"(anonymous_2)","decl":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"loc":{"start":{"line":19,"column":38},"end":{"line":20,"column":null}}},"2":{"name":"(anonymous_3)","decl":{"start":{"line":22,"column":2},"end":{"line":22,"column":10}},"loc":{"start":{"line":22,"column":10},"end":{"line":24,"column":null}}},"3":{"name":"(anonymous_4)","decl":{"start":{"line":26,"column":2},"end":{"line":26,"column":16}},"loc":{"start":{"line":26,"column":22},"end":{"line":30,"column":null}}},"4":{"name":"(anonymous_5)","decl":{"start":{"line":32,"column":2},"end":{"line":32,"column":9}},"loc":{"start":{"line":32,"column":13},"end":{"line":34,"column":null}}},"5":{"name":"(anonymous_6)","decl":{"start":{"line":36,"column":2},"end":{"line":36,"column":18}},"loc":{"start":{"line":36,"column":18},"end":{"line":39,"column":null}}}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":13},"end":{"line":11,"column":38}},"type":"binary-expr","locations":[{"start":{"line":11,"column":13},"end":{"line":11,"column":38}},{"start":{"line":11,"column":13},"end":{"line":11,"column":38}}]}},"s":{"0":30,"1":190,"2":38,"3":38,"4":38,"5":38,"6":38,"7":0,"8":0,"9":0,"10":9992,"11":0,"12":0,"13":98},"f":{"0":30,"1":38,"2":38,"3":0,"4":9992,"5":0},"b":{"0":[38,38]}}
...

The lcov-report of the Cypress run: HTML report of the Cypress run

merging与2相加nyc merge之后,我得到这个结果`:

  ".../frontend/src/main/resources/ngapp/src/app/common/app-components/language-selector/language-selector.component.ts": {
    "path": ".../frontend/src/main/resources/ngapp/src/app/common/app-components/language-selector/language-selector.component.ts",
    "statementMap": {
      "0": {
        "start": {
          "line": 11,
          "column": 38
        },
        "end": {
          "line": 11,
          "column": null
        }
      },
      "1": {
        "start": {
          "line": 19,
          "column": 38
        },
        "end": {
          "line": 19,
          "column": null
        }
      },
      "2": {
        "start": {
          "line": 16,
          "column": 11
        },
        "end": {
          "line": 16,
          "column": 38
        }
      },
      "3": {
        "start": {
          "line": 17,
          "column": 12
        },
        "end": {
          "line": 17,
          "column": 40
        }
      },
      "4": {
        "start": {
          "line": 18,
          "column": 21
        },
        "end": {
          "line": 18,
          "column": 45
        }
      },
      "5": {
        "start": {
          "line": 19,
          "column": 12
        },
        "end": {
          "line": 19,
          "column": 38
        }
      },
      "6": {
        "start": {
          "line": 23,
          "column": 4
        },
        "end": {
          "line": 23,
          "column": null
        }
      },
      "7": {
        "start": {
          "line": 27,
          "column": 4
        },
        "end": {
          "line": 27,
          "column": null
        }
      },
      "8": {
        "start": {
          "line": 28,
          "column": 4
        },
        "end": {
          "line": 28,
          "column": null
        }
      },
      "9": {
        "start": {
          "line": 29,
          "column": 4
        },
        "end": {
          "line": 29,
          "column": null
        }
      },
      "10": {
        "start": {
          "line": 33,
          "column": 4
        },
        "end": {
          "line": 33,
          "column": null
        }
      },
      "11": {
        "start": {
          "line": 37,
          "column": 4
        },
        "end": {
          "line": 37,
          "column": null
        }
      },
      "12": {
        "start": {
          "line": 38,
          "column": 4
        },
        "end": {
          "line": 38,
          "column": null
        }
      },
      "13": {
        "start": {
          "line": 11,
          "column": 13
        },
        "end": {
          "line": 11,
          "column": null
        }
      }
    },
    "fnMap": {
      "0": {
        "name": "(anonymous_1)",
        "decl": {
          "start": {
            "line": 11,
            "column": 38
          },
          "end": {
            "line": 11,
            "column": null
          }
        },
        "loc": {
          "start": {
            "line": 11,
            "column": 38
          },
          "end": {
            "line": 11,
            "column": null
          }
        }
      },
      "1": {
        "name": "(anonymous_2)",
        "decl": {
          "start": {
            "line": 15,
            "column": 2
          },
          "end": {
            "line": 15,
            "column": null
          }
        },
        "loc": {
          "start": {
            "line": 19,
            "column": 38
          },
          "end": {
            "line": 20,
            "column": null
          }
        }
      },
      "2": {
        "name": "(anonymous_3)",
        "decl": {
          "start": {
            "line": 22,
            "column": 2
          },
          "end": {
            "line": 22,
            "column": 10
          }
        },
        "loc": {
          "start": {
            "line": 22,
            "column": 10
          },
          "end": {
            "line": 24,
            "column": null
          }
        }
      },
      "3": {
        "name": "(anonymous_4)",
        "decl": {
          "start": {
            "line": 26,
            "column": 2
          },
          "end": {
            "line": 26,
            "column": 16
          }
        },
        "loc": {
          "start": {
            "line": 26,
            "column": 22
          },
          "end": {
            "line": 30,
            "column": null
          }
        }
      },
      "4": {
        "name": "(anonymous_5)",
        "decl": {
          "start": {
            "line": 32,
            "column": 2
          },
          "end": {
            "line": 32,
            "column": 9
          }
        },
        "loc": {
          "start": {
            "line": 32,
            "column": 13
          },
          "end": {
            "line": 34,
            "column": null
          }
        }
      },
      "5": {
        "name": "(anonymous_6)",
        "decl": {
          "start": {
            "line": 36,
            "column": 2
          },
          "end": {
            "line": 36,
            "column": 18
          }
        },
        "loc": {
          "start": {
            "line": 36,
            "column": 18
          },
          "end": {
            "line": 39,
            "column": null
          }
        }
      }
    },
    "branchMap": {
      "0": {
        "loc": {
          "start": {
            "line": 11,
            "column": 13
          },
          "end": {
            "line": 11,
            "column": 38
          }
        },
        "type": "binary-expr",
        "locations": [
          {
            "start": {
              "line": 11,
              "column": 13
            },
            "end": {
              "line": 11,
              "column": 38
            }
          },
          {
            "start": {
              "line": 11,
              "column": 13
            },
            "end": {
              "line": 11,
              "column": 38
            }
          }
        ]
      }
    },
    "s": {
      "0": 183,
      "1": 983,
      "2": 245,
      "3": 245,
      "4": 233,
      "5": 212,
      "6": 190,
      "7": 0,
      "8": 0,
      "9": 0,
      "10": 49960,
      "11": 3,
      "12": 0,
      "13": 490,
      "14": null,
      "15": null,
      "16": null,
      "17": null,
      "18": null,
      "19": null,
      "20": null,
      "21": null
    },
    "f": {
      "0": 183,
      "1": 211,
      "2": 190,
      "3": 0,
      "4": 49960,
      "5": 0,
      "6": null,
      "7": null,
      "8": null,
      "9": null,
      "10": null
    },
    "b": {
      "0": [
        190,
        190
      ]
    }
  }

运行nyc report --reporter=lcov --reporter=text-summary会产生以下结果:

merged report

这会是什么问题呢?我try 了这里的https://github.com/istanbuljs/nyc/issues/1302个建议中的一些,但都没有奏效.迁移到早期版本的ISTAMBUL(例如14.1)会产生胡言乱语的数据(它不会解析我的Typescript 文件).

Update:个 下面是我用来生成输出的命令:

  1. 首先,我验证我在karmacypress文件夹中是否有现有的报告.
  2. 命令:
    "coverage-merge-and-report": "mkdir -p coverage/toMerge && cp coverage/karma/coverage-final.json coverage/toMerge/ && cp coverage/cypress/coverage-final.json coverage/toMerge/coverage-final-cypress.json && nyc merge coverage/toMerge coverage/toMerge/merged.json && npx nyc report --reporter=lcov --reporter=text-summary --temp-dir=coverage/toMerge --report-dir=coverage/merged-report"

The problem with it was with the final part: npx nyc report --reporter=lcov --reporter=text-summary --report-dir=... scans for the .nyc_output folder I belive, and the reportes is not right either. enter image description here

我将其更改为:npx nyc report --reporter=html --reporter=text-summary -t coverage/test --report-dir=...,现在它产生了一个正确的答案.

推荐答案

如果我接受你的业力和 cypress 的输出,把它们放在/cover文件夹中的一个干净的项目中,然后运行下面的语句(注释行是语法)

// nyc merge <input-directory> [output-file]
   nyc merge cover cover-merged.json

我得到的合并文件和你的不一样.

抽查

  • 在Karma语句中,Map(index:0)是第16行,它的计数为11
  • In Cypress语句映射行16在index:2中,计数为38
  • 我的合并输出在index:2中也有第16行,计数为49

由于您的数字要大得多,是否还有其他文件被拖入合并中?

此外,在 cypress lcov-report中,行16的计数是147,而在 cypress coverage-final.json中,行16计数是38.

首先,我会集中精力比较这json个文件.这个问题中没有任何其他线索,但请判断您的nyc merge <input-directory> [output-file]命令的参数,并寻找可能会增加计数的先前运行的输出文件.

VS Code side-by-side

enter image description here

Angular相关问答推荐

RFDC.CommonJS或AMD依赖项可能会导致优化救助ANGURAL PROCEMENT with ngx-charts lib

为什么我的自定义.d.ts不起作用?LeaderLine不是构造函数

图像未显示在视图屏幕上-Angular 投影

如何将管道异步化添加到不在html模板中的观察对象的Angular ?

Angular 16-错误NG8002:无法绑定到NGModel,因为它不是输入的已知属性

从Angular 前端访问ASP.NET Core 8 Web API时出现CORS错误

如何将Angular 服务包含在延迟加载的独立组件路由中?

nx serve正在忽略@angular/localize/init的导入"

Ng serve不工作,没有错误或消息来显示问题所在

Angular 单位测试表

使用 RXJS 进行空闲/不活动跟踪

大型 Angular 12 应用程序 - 我如何管理 js 文件

Angular 按钮指令错误地附加子元素

通过 SignalR 事件组件重定向Angular 页面后不起作用

Angular 2 二传手与 ngOnChanges

如何以像素为单位将属性绑定到 style.width?

如何将新的 FormGroup 或 FormControl 添加到表单

Angular 2 组件不是任何 NgModule 的一部分

从 angular2 模板调用静态函数

如何在 Angular CLI 的构建时插入内部版本号或时间戳