Angular + Cypress 代码覆盖率报告不起作用
Angular + Cypress code coverage reporting not working
我一直在尝试让 Cypress 代码覆盖率与我的 Angular 生产项目一起使用,但无济于事。
为了尝试帮助诊断它,我创建了一个最小的实施项目,以确保我没有在生产版本中引入任何奇怪的东西,我不认为我是因为同样的问题仍在发生。它开始让我发疯!
我已经使用了一些参考资料,据我所知,我已经准备好了我需要的东西:
据我所知,Angular 和 Cypress 方面都已连接,并且正在 .nyc_output 文件夹和覆盖率报告中获取输出。然而,该报告并未指出打字稿行覆盖率或包括这些统计数据。
我看过 但似乎没有帮助。
代码检测(webpack 扩展 + angular.json):
module.exports = {
module: {
rules: [
{
test: /\.(js|ts)$/,
loader: "istanbul-instrumenter-loader",
options: { esModules: true },
enforce: "post",
include: require("path").join(__dirname, "..", "src"),
exclude: [
/\.(e2e|spec)\.ts$/,
/node_modules/,
/(ngfactory|ngstyle)\.js/,
],
},
],
},
};
"serve": {
"builder": "ngx-build-plus:dev-server",
"options": {
"browserTarget": "architecture-testing:build",
"extraWebpackConfig": "./cypress/coverage.webpack.js",
"sourceMap": true
},
"configurations": {
"production": {
"browserTarget": "architecture-testing:build:production"
}
}
}
Cypress 似乎正在记录和保存覆盖范围:
const registerCodeCoverageTasks = require("@cypress/code-coverage/task");
module.exports = (on, config) => {
registerCodeCoverageTasks(on, config);
return config;
};
out.json 似乎具有正确的文件和代码映射:
:
package.json(纽约配置 + 部门):
{
"name": "architecture-testing",
"version": "0.0.0",
"scripts": {
"postinstall": "ngcc",
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"precypress": "rimraf .nyc_output coverage",
"cypress": "ng run architecture-testing:cypress-run",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
},
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"exclude": [
"coverage/**",
"cypress/**",
"**/*.spec.ts"
]
},
"private": true,
"dependencies": {
"@angular/animations": "~9.1.9",
"@angular/common": "~9.1.9",
"@angular/compiler": "~9.1.9",
"@angular/core": "~9.1.9",
"@angular/forms": "~9.1.9",
"@angular/platform-browser": "~9.1.9",
"@angular/platform-browser-dynamic": "~9.1.9",
"@angular/router": "~9.1.9",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.901.7",
"@angular/cli": "~9.1.7",
"@angular/compiler-cli": "~9.1.9",
"@briebug/cypress-schematic": "^3.3.0",
"@cypress/code-coverage": "^3.8.1",
"@cypress/webpack-preprocessor": "5.4.1",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"cypress": "^4.8.0",
"istanbul-instrumenter-loader": "^3.0.1",
"istanbul-lib-coverage": "^3.0.0",
"ngx-build-plus": "^9.0.6",
"nyc": "^15.1.0",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.19",
"ts-loader": "7.0.5",
"ts-node": "^8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.8.3"
}
}
规格文件:
it('does something', () => {
cy.visit('http://localhost:4200');
cy.get('[data-cy=button-one]').click();
cy.get('[data-cy=button-output]').should('have.text', 'you clicked button 1');
});
抱歉,时间太长了,但我不知道下一步该去哪里。如果你能指出任何方向,非常感谢。
根据答案调查更新:
查看@cypress/code-coverage 的过去版本,看来我的问题是在插件的 v3.3.0 中引入的。 v3.2.* 的所有版本在降级我的最小项目时都对我有用。查看 v3.3.0 的文档更改后,自述文件中的关键信息是:
**Note:** if you have `all: true` NYC option set, this plugin will check the produced `.nyc_output/out.json` before generating the final report. If the `out.json` file does not have information for some files that should be there according to `include` list, then an empty placeholder will be included, see [PR 208](https://github.com/cypress-io/code-coverage/pull/208).
我最初的纽约配置是:
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"exclude": [
"coverage/**",
"cypress/**",
"**/*.spec.ts"
]
}
所以出于某种原因,即使我有在 out.json 中测试的文件的指标,也会创建第二个“空占位符”节点并覆盖后续报告生成。我猜这可能是我的设置的错误或问题,所以我会询问创作者。
如果我将 nyc 配置更改为:
,我现在可以看到覆盖范围
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"include": [
"src/**/*.ts"
],
"exclude": [
"coverage/**",
"cypress/**",
"**/*.spec.ts"
]
}
这确实意味着,如果我不通过测试命中文件,它将不会作为空占位符包含在内,因为“all”: true 不再存在。
查看@briebug/cypress-schematic@3.3.0 这似乎没有引起任何问题(同样发生在不使用他们的构建器的情况下)但已被提出为一个 here and here.
将 ang-cy-cov-example 与您的 package.json 进行比较,主要区别在于他使用 @cypress/code-coverage@1.14.0,而您拥有最新的 v3.8.1。
改回此 v1.14.0 适用于您的设置。由于您的信息表明数据出现在 .nyc_output/out.json
中,我使用命令行 ./node_modules/.bin/nyc report
进行了测试,它可以在控制台中快速查看。
比较两个版本 .nyc_output/out.json
,各个节点在结构上相同,即具有正确的部分(路径、statementMap、inputSourceMap 等)。
有两种附加节点
其他文件如karma.conf.js、coverage.webpack.js、cy-ts-preprocessor.js、integration/spec.ts、support/commands。 ts - 我们对此不感兴趣。
我们感兴趣的文件在文件末尾重复,但重复项没有覆盖率指标。
例如
main.ts 的第一个副本,带有指标
"path-to\src\main.ts": {
"path": "path-to\src\main.ts",
"statementMap": {
...
},
"1": {
...
},
"2": {
...
}
},
"fnMap": {},
"branchMap": {
...
},
"s": {
"0": 1, // indicates one visit to this statement
"1": 0,
"2": 1
},
"f": {},
"b": {
"0": [
0,
1
]
},
"inputSourceMap": {
...
},
"_coverageSchema": "332fd63041d2c1bcb487cc26dd0d5f7d97098a6c",
"hash": "5959c383a9744c99a600a28ff82b12f0a540c5e6"
},
main.ts 的第二个副本,没有指标
"path-to/src/main.ts": {
"path": "path-to/src/main.ts",
"statementMap": {},
"fnMap": {},
"branchMap": {},
"s": {}, // no metrics recorded here
"f": {},
"b": {}
},
因此,结论是 NYC 报告正在用第二个节点的空指标替换第一个节点指标。
我跳过了版本,v3.2.0 是我发现的最新版本。
在添加节点模块时还要注意这个警告,但不能说它是否是一个促成因素。
warning " > @briebug/cypress-schematic@3.3.0" has incorrect peer dependency "cypress@^3.6.1"
故障点
基本问题在任务-utils.js.
ref getting allFiles
const allFiles = globby.sync(patterns, { absolute: true })
其中 globby
returns 甚至在 Windows
上带有正斜杠的路径
const coveredPaths = coverageKeys.map(key => nycCoverage[key].path)
密钥已保存在 out.json
中,在 Windows 中使用反斜杠。
一个快速的解决办法是在此时规范化路径
const coveredPaths = coverageKeys.map(key => nycCoverage[key].path)
.map(path => path.replace(/\/g, '/')) // Compare "normalized" paths
修补'/node_modules/@cypress/code-coverage/task-utils.js'解决了这个问题。
此补丁现已应用到 pull request 中,看起来像 v3.8.6
参考 Handle backslashes in coverage file path(2020 年 12 月)。
这是(部分)link 所说的:
This PR is included in version 3.8.6
The release is available on:
npm package (@latest dist-tag)
GitHub release
我一直在尝试让 Cypress 代码覆盖率与我的 Angular 生产项目一起使用,但无济于事。
为了尝试帮助诊断它,我创建了一个最小的实施项目,以确保我没有在生产版本中引入任何奇怪的东西,我不认为我是因为同样的问题仍在发生。它开始让我发疯!
我已经使用了一些参考资料,据我所知,我已经准备好了我需要的东西:
据我所知,Angular 和 Cypress 方面都已连接,并且正在 .nyc_output 文件夹和覆盖率报告中获取输出。然而,该报告并未指出打字稿行覆盖率或包括这些统计数据。
我看过
代码检测(webpack 扩展 + angular.json):
module.exports = {
module: {
rules: [
{
test: /\.(js|ts)$/,
loader: "istanbul-instrumenter-loader",
options: { esModules: true },
enforce: "post",
include: require("path").join(__dirname, "..", "src"),
exclude: [
/\.(e2e|spec)\.ts$/,
/node_modules/,
/(ngfactory|ngstyle)\.js/,
],
},
],
},
};
"serve": {
"builder": "ngx-build-plus:dev-server",
"options": {
"browserTarget": "architecture-testing:build",
"extraWebpackConfig": "./cypress/coverage.webpack.js",
"sourceMap": true
},
"configurations": {
"production": {
"browserTarget": "architecture-testing:build:production"
}
}
}
Cypress 似乎正在记录和保存覆盖范围:
const registerCodeCoverageTasks = require("@cypress/code-coverage/task");
module.exports = (on, config) => {
registerCodeCoverageTasks(on, config);
return config;
};
out.json 似乎具有正确的文件和代码映射:
package.json(纽约配置 + 部门):
{
"name": "architecture-testing",
"version": "0.0.0",
"scripts": {
"postinstall": "ngcc",
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"precypress": "rimraf .nyc_output coverage",
"cypress": "ng run architecture-testing:cypress-run",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
},
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"exclude": [
"coverage/**",
"cypress/**",
"**/*.spec.ts"
]
},
"private": true,
"dependencies": {
"@angular/animations": "~9.1.9",
"@angular/common": "~9.1.9",
"@angular/compiler": "~9.1.9",
"@angular/core": "~9.1.9",
"@angular/forms": "~9.1.9",
"@angular/platform-browser": "~9.1.9",
"@angular/platform-browser-dynamic": "~9.1.9",
"@angular/router": "~9.1.9",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.901.7",
"@angular/cli": "~9.1.7",
"@angular/compiler-cli": "~9.1.9",
"@briebug/cypress-schematic": "^3.3.0",
"@cypress/code-coverage": "^3.8.1",
"@cypress/webpack-preprocessor": "5.4.1",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"cypress": "^4.8.0",
"istanbul-instrumenter-loader": "^3.0.1",
"istanbul-lib-coverage": "^3.0.0",
"ngx-build-plus": "^9.0.6",
"nyc": "^15.1.0",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.19",
"ts-loader": "7.0.5",
"ts-node": "^8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.8.3"
}
}
规格文件:
it('does something', () => {
cy.visit('http://localhost:4200');
cy.get('[data-cy=button-one]').click();
cy.get('[data-cy=button-output]').should('have.text', 'you clicked button 1');
});
抱歉,时间太长了,但我不知道下一步该去哪里。如果你能指出任何方向,非常感谢。
根据答案调查更新:
查看@cypress/code-coverage 的过去版本,看来我的问题是在插件的 v3.3.0 中引入的。 v3.2.* 的所有版本在降级我的最小项目时都对我有用。查看 v3.3.0 的文档更改后,自述文件中的关键信息是:
**Note:** if you have `all: true` NYC option set, this plugin will check the produced `.nyc_output/out.json` before generating the final report. If the `out.json` file does not have information for some files that should be there according to `include` list, then an empty placeholder will be included, see [PR 208](https://github.com/cypress-io/code-coverage/pull/208).
我最初的纽约配置是:
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"exclude": [
"coverage/**",
"cypress/**",
"**/*.spec.ts"
]
}
所以出于某种原因,即使我有在 out.json 中测试的文件的指标,也会创建第二个“空占位符”节点并覆盖后续报告生成。我猜这可能是我的设置的错误或问题,所以我会询问创作者。
如果我将 nyc 配置更改为:
,我现在可以看到覆盖范围"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"include": [
"src/**/*.ts"
],
"exclude": [
"coverage/**",
"cypress/**",
"**/*.spec.ts"
]
}
这确实意味着,如果我不通过测试命中文件,它将不会作为空占位符包含在内,因为“all”: true 不再存在。
查看@briebug/cypress-schematic@3.3.0 这似乎没有引起任何问题(同样发生在不使用他们的构建器的情况下)但已被提出为一个 here and here.
将 ang-cy-cov-example 与您的 package.json 进行比较,主要区别在于他使用 @cypress/code-coverage@1.14.0,而您拥有最新的 v3.8.1。
改回此 v1.14.0 适用于您的设置。由于您的信息表明数据出现在 .nyc_output/out.json
中,我使用命令行 ./node_modules/.bin/nyc report
进行了测试,它可以在控制台中快速查看。
比较两个版本 .nyc_output/out.json
,各个节点在结构上相同,即具有正确的部分(路径、statementMap、inputSourceMap 等)。
有两种附加节点
其他文件如karma.conf.js、coverage.webpack.js、cy-ts-preprocessor.js、integration/spec.ts、support/commands。 ts - 我们对此不感兴趣。
我们感兴趣的文件在文件末尾重复,但重复项没有覆盖率指标。
例如
main.ts 的第一个副本,带有指标
"path-to\src\main.ts": {
"path": "path-to\src\main.ts",
"statementMap": {
...
},
"1": {
...
},
"2": {
...
}
},
"fnMap": {},
"branchMap": {
...
},
"s": {
"0": 1, // indicates one visit to this statement
"1": 0,
"2": 1
},
"f": {},
"b": {
"0": [
0,
1
]
},
"inputSourceMap": {
...
},
"_coverageSchema": "332fd63041d2c1bcb487cc26dd0d5f7d97098a6c",
"hash": "5959c383a9744c99a600a28ff82b12f0a540c5e6"
},
main.ts 的第二个副本,没有指标
"path-to/src/main.ts": {
"path": "path-to/src/main.ts",
"statementMap": {},
"fnMap": {},
"branchMap": {},
"s": {}, // no metrics recorded here
"f": {},
"b": {}
},
因此,结论是 NYC 报告正在用第二个节点的空指标替换第一个节点指标。
我跳过了版本,v3.2.0 是我发现的最新版本。
在添加节点模块时还要注意这个警告,但不能说它是否是一个促成因素。
warning " > @briebug/cypress-schematic@3.3.0" has incorrect peer dependency "cypress@^3.6.1"
故障点
基本问题在任务-utils.js.
ref getting allFiles
const allFiles = globby.sync(patterns, { absolute: true })
其中 globby
returns 甚至在 Windows
const coveredPaths = coverageKeys.map(key => nycCoverage[key].path)
密钥已保存在 out.json
中,在 Windows 中使用反斜杠。
一个快速的解决办法是在此时规范化路径
const coveredPaths = coverageKeys.map(key => nycCoverage[key].path)
.map(path => path.replace(/\/g, '/')) // Compare "normalized" paths
修补'/node_modules/@cypress/code-coverage/task-utils.js'解决了这个问题。
此补丁现已应用到 pull request 中,看起来像 v3.8.6
参考 Handle backslashes in coverage file path(2020 年 12 月)。
这是(部分)link 所说的:
This PR is included in version 3.8.6
The release is available on:
npm package (@latest dist-tag)
GitHub release