您如何将伊斯坦布尔代码覆盖率与转译的 Typescript 一起使用?

Posted

技术标签:

【中文标题】您如何将伊斯坦布尔代码覆盖率与转译的 Typescript 一起使用?【英文标题】:How do you use Istanbul Code Coverage with transpiled Typescript? 【发布时间】:2016-03-05 18:38:33 【问题描述】:

我整个上午都在阅读有关这方面的文章,试图正确设置我的环境。但由于某种原因,我没有得到它。我的设置-

/app
    ... source (mixed js and ts)
/scripts
    ... copied source (js)
    typescripts.js // transpiled typescript with inline mapping

测试运行良好,并且 chrome 调试器中的映射调试被正确映射。但伊斯坦布尔将typescripts.js 文件视为一个文件,而不是几十个其他文件的串联。

为了生成打字稿源,我使用了gulp-typescript。源码(不包括测试)被转译到前面提到的typescripts.js,测试被单独转译并复制到/scripts

  var ts = require('gulp-typescript');
  var sourcemaps = require('gulp-sourcemaps');
  var concat = require('gulp-concat');

  module.exports = function (gulp, config) 
     'use strict';

     // Runs dot ts files found in `www` through the typescript compiler and copies them as js 
     // files to the scripts directory

     gulp.task('typescript', ['typescript:tests'], function () 
        return gulp.src(config.paths.typescript) // [ './www/app/**/*.ts', '!./www/app/**/*.test.ts', '!./www/app/**/*.mock.ts' ]
           .pipe(sourcemaps.init())
           .pipe(ts(ts.createProject(config.paths.tsConfig))) // './tsconfig.json'
           .js
           .pipe(concat(config.sourcemaps.dest)) // typescripts.js
           .pipe(sourcemaps.write(config.sourcemaps)) //  includeContent: false, sourceRoot: '/app'  - i've also tried absolute local path
           .pipe(gulp.dest(config.paths.tmpScripts)); // ./www/scripts


     );

     gulp.task('typescript:tests', [], function() 
        return gulp.src(config.paths.typescriptTests) // [ './www/app/**/*.test.ts', './www/app/**/*.mock.ts' ]
           .pipe(ts(ts.createProject(config.paths.tsConfig))) // './tsconfig.json'
           .pipe(gulp.dest(config.paths.tmpScripts)); // ./www/scripts
     );
  ;

生成的typescripts.js 具有内联源映射。使用 sourcemap,十几个 ts 文件大小为 106kb。

所以从这里开始测试和调试工作正常。

现在,为了让伊斯坦布尔代码覆盖率正常工作,我安装了 karma-sourcemap-loader 并将其添加到预处理器中。

preprocessors: 
    'www/scripts/typescripts.js': ['sourcemap'],
    'www/scripts/**/*.js': ['coverage']
,

我认为这是我需要做的。但它没有显示源文件的代码覆盖率。我尝试了C:/ 的绝对路径,但这也不起作用。我还尝试了 gulp-sourcemaps 中的不同选项,例如添加源(将文件推送到 160kb),但也没有。

有人让这个工作吗?有什么想法我可能做错了吗?

【问题讨论】:

【参考方案1】:

TL;DR:有一个工具:https://github.com/SitePen/remap-istanbul 被描述为通过源地图重新映射伊斯坦布尔覆盖范围的工具

Sitepan 上的article 对其进行了更详细的描述:

Intern 以及其他 javascript 测试框架都使用了伊斯坦布尔 用于他们的代码覆盖率分析。随着我们开始越来越多地采用 TypeScript 用于我们自己的项目,我们继续努力获得 清楚地了解我们的代码覆盖率,因为所有报告仅包括在内 我们发出的代码的覆盖率。我们不得不尝试使用编译器 在我们的脑海中试图找出我们缺少测试覆盖的地方。 我们还喜欢围绕我们的覆盖范围设置指标,让我们跟踪我们是否 正朝着正确的方向前进。

我们中的一些人开始探索我们如何能够完成 将覆盖率报告映射回其起源并经过一段时间 工作,我们创建了 remap-istanbul,一个允许伊斯坦布尔的包 覆盖信息被映射回其源,当有 源地图可用。虽然我们一直专注于 TypeScript,但它 可以在任何对发射代码产生覆盖的地方使用, 包括上面提到的工具!

如何通过 gulp 使用该工具:https://github.com/SitePen/remap-istanbul#gulp-plugin

【讨论】:

【参考方案2】:

如果您希望伊斯坦布尔的源地图支持,您可以使用 1.0 alpha 版本,因为当前版本支持源地图。我在http://github.com/typings/typings 中使用ts-node 设置了它(请参阅https://github.com/typings/typings/blob/bff1abad91dabec1cd8a744e0dd3f54b613830b5/package.json#L19),并且正在映射源代码。它看起来很棒,并且很高兴让我的测试和代码覆盖都在零转译的情况下在进程中运行。当然,您可以将 Istanbul 1.0 与转译的 JavaScript 一起使用。

对于您正在使用的浏览器实现,我必须查看更多有关您正在执行的操作的代码才能看到这对您有用,但请尝试 1.0.0-alpha.2 看看会发生什么。

【讨论】:

链接存储库中没有测试。 如果您浏览 repo 而不是 master,则在提交哈希处。如果您在进行最新测试,可以查看github.com/typings/core。例如,github.com/typings/typings/blob/…。【参考方案3】:

正如布莱克布雷所说。 Istanbul 1.x 处理得很好。

下面是一个使用 Jasmine 执行的纯 npm 脚本示例。

见https://github.com/Izhaki/Typescript-Jasmine-Istanbul-Boilerplate。

package.json(相关的东西)


  "scripts": 
    "postinstall": "typings install dt~jasmine --save --global",
    "test": "ts-node node_modules/.bin/jasmine JASMINE_CONFIG_PATH=jasmine.json",
    "test:coverage": "ts-node node_modules/istanbul/lib/cli.js cover -e .ts  -x \"*.d.ts\" -x \"*.spec.ts\" node_modules/jasmine/bin/jasmine.js -- JASMINE_CONFIG_PATH=jasmine.json"
  ,
  "devDependencies": 
    "istanbul": "^1.1.0-alpha.1",
    "jasmine": "^2.4.1",
    "ts-node": "^0.9.3",
    "typescript": "^1.8.10",
    "typings": "^1.3.1"
  ,

输出

【讨论】:

链接存储库中的示例不起作用。它抛出一个错误:SyntaxError: missing ) after argument list. @ShaunLuttin 打开 github 问题?您使用的是哪个节点版本? @ShaunLuttin 它应该可以工作(并且错误似乎是一个明显的问题)。您能否打开一个 github 问题并提供更多详细信息? @ShaunLuttin,windows 代码也可以在 linux 上运行,所以我删除了你的注释,只是将代码更改为适用于 windows/linux 的版本。【参考方案4】:

这是回购作品。我运行了 repo,可以看到测试正在运行。还会生成 html 视图。 https://github.com/Izhaki/Typescript-Jasmine-Istanbul-Boilerplate

【讨论】:

【参考方案5】:

提供的示例均不适用于我的 Node.JS 项目(用 TypeScript 编写)。我想在 Jasmine 中运行单元测试,并被伊斯坦布尔覆盖。

我最终让它与以下内容一起工作。

package.json:


  "scripts": 
    "lint": "tslint 'src/**/*.ts'",
    "remap": "./node_modules/.bin/remap-istanbul -i ./coverage/coverage-final.json -t html -o ./coverage && rimraf ./coverage/dist",
    "test": "npm run lint && rimraf dist coverage && tsc --project tsconfig-test.json && ./node_modules/.bin/istanbul cover ./node_modules/.bin/jasmine JASMINE_CONFIG_PATH=jasmine.json && npm run remap"
  ,
  "devDependencies": 
    "@types/jasmine": "2.8.6",
    "@types/node": "9.6.6",
    "istanbul": "0.4.5",
    "jasmine": "3.1.0",
    "remap-istanbul": "0.11.1",
    "rimraf": "2.6.2",
    "tslint": "5.9.1",
    "typescript": "2.8.1"
  

jasmine.json


  "spec_dir": "dist",
  "spec_files": [
    "**/*.spec.js"
  ],
  "stopSpecOnExpectationFailure": false,
  "random": false

.istanbul.yml

instrumentation:
  root: ./dist
  excludes: ['**/*.spec.js', '**/fixtures/*.js']
  include-all-sources: true
reporting:
  reports:
    - html
    - json
    - text-summary
  dir: ./coverage

tsconfig-test.json


  "compilerOptions": 
    "declaration": true,
    "lib": [
      "dom",
      "es6"
    ],
    "module": "commonjs",
    "noImplicitAny": true,
    "outDir": "dist",
    "sourceMap": true,
    "target": "es5"
  ,
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]

【讨论】:

以上是关于您如何将伊斯坦布尔代码覆盖率与转译的 Typescript 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何从代码覆盖率伊斯坦布尔记者中排除模拟文件

您如何使用伊斯坦布尔检查单个文件的覆盖率?

React 与 Puppeteer + 伊斯坦布尔的代码覆盖率

Ember CLI 代码覆盖率报告

如何获得业力覆盖率(伊斯坦布尔)来检查所有源文件的覆盖率?

如何从终端中的谷歌测试套件获得c ++代码超额?