简体   繁体   中英

How do you use Istanbul Code Coverage with transpiled Typescript?

I've been reading articles on this all morning trying to get my environment setup correctly. But for some reason I'm not getting it. My setup-

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

Tests run fine, and with the mapping debugging in the chrome debugger is mapped correctly. But Istanbul sees the typescripts.js file as one file instead of the concatenation of dozens of other files.

To generate the typescript source I'm using gulp-typescript . The source (excluding tests) are transpiled to the aforementioned typescripts.js , and the tests are transpiled individually and copied to /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
     });
  };

The resulting typescripts.js has the inline sourcemap. With the sourcemap, the dozen or so ts files results in 106kb.

So from here tests and debugging works fine.

Now in an attempt to get Istanbul code coverage working properly i've installed karma-sourcemap-loader and added it to the preprocessors.

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

I'd think this is what I'd need to do. But it does not show code coverage on the source files. I tried the absolute path from C:/ but that didn't work either. I also tried the different options in gulp-sourcemaps like adding source (which pushed the file to 160kb) but no like either.

Has anyone gotten this to work? Any ideas what I could be doing wrong?

TL;DR: There is a tool: https://github.com/SitePen/remap-istanbul described as A tool for remapping Istanbul coverage via Source Maps

The article on Sitepan describes it in more detail:

Intern as well as other JavaScript testing frameworks utilise Istanbul for their code coverage analysis. As we started to adopt more and more TypeScript for our own projects, we continued to struggle with getting a clear picture of our code coverage as all the reports only included the coverage of our emitted code. We had to try to use the compilers in our minds to try to figure out where we were missing test coverage. We also like to set metrics around our coverage to let us track if we are headed the right direction.

A couple of us started exploring how we might be able to accomplish mapping the coverage report back to its origins and after a bit of work, we created remap-istanbul, a package that allows Istanbul coverage information to be mapped back to its source when there are Source Maps available. While we have been focused on TypeScript, it can be used wherever the coverage is being produced on emitted code, including the tools mentioned above!

How to use the tool with gulp: https://github.com/SitePen/remap-istanbul#gulp-plugin

If you want source map support with Istanbul, you can use the 1.0 alpha release as the current release does not support source maps. I have it set up using ts-node in http://github.com/typings/typings (see https://github.com/typings/typings/blob/bff1abad91dabec1cd8a744e0dd3f54b613830b5/package.json#L19 ) and source code is being mapped. It looks great and is nice to have my tests and code coverage all running in-process with zero transpilation. Of course, you can use Istanbul 1.0 with the transpiled JavaScript.

For the browser implementation you're using, I'd have to see more of code of what you're doing to see this'll just work for you, but try the 1.0.0-alpha.2 and see what happens.

As blakeembrey mentioned. Istanbul 1.x handles it well.

Below an example of pure npm script that does it with Jasmine.

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

package.json (the relevant stuff)

{
  "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"
  },
}

Output

图片

This is repo works. I ran the repo and can see the tests running. Html view is also generated. https://github.com/Izhaki/Typescript-Jasmine-Istanbul-Boilerplate

None of the examples provided worked for my Node.JS project (written in TypeScript). I wanted to run unit tests in Jasmine, and covered by Istanbul.

I ended up getting it working with the following.

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"
  ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM