Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 270
micah Avatar asked Dec 01 '15 18:12

micah


3 Answers

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

like image 61
Martin Vseticka Avatar answered Nov 15 '22 06:11

Martin Vseticka


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.

like image 28
blakeembrey Avatar answered Nov 15 '22 06:11

blakeembrey


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

image

like image 3
Izhaki Avatar answered Nov 15 '22 05:11

Izhaki