29
votes

We've just started a project in Typescript and we need to get code coverage figures.

Our existing JavaScript projects use Instanbul in Grunt for coverage. We are unsure how to replicate this for TypeScript.

Are there any tools for generating code coverage from the TypeScript code itself? Or do we run the Istanbul (or similar) tool against the generated JavaScript code.

6
Too bad this is closed. As of July 2017 istanbul seems to be moved to nyc, so use nyc instead. - paibamboo

6 Answers

22
votes

On the TypeScript team, we just use regular code coverage tools on the compiled JavaScript. We've found this to be more than sufficient, since usually for code coverage you are looking at total coverage % (which doesn't change significantly) or are deep-diving at expression-level (which also doesn't change significantly).

If you found a tool that supported it (I'm not aware of any yet), you could in theory use the source maps emitted by the compiler to map the coverage data back to the TypeScript code. It's probably not worth the trouble.

20
votes

Update: August 2016

It is now possible to run Istanbul against TypeScript source code using Istanbul v1 (currently in the alpha stage) along with TypeScript Node.

The following assumes that you are using Mocha as a test framework and that all test code is under the standard test/ directory.

First, install the requisite packages:

npm install --save-dev mocha ts-node
npm install --save-dev --save-exact [email protected]

Then include something like the following in your package.json:

"scripts": {
   "test": "istanbul cover -e .ts _mocha -- --compilers ts:ts-node/register"
}

That's it. Run npm test and you'll be covered.

See my Deep Map project for a working example in which the test files are kept in the same directory as the source code. Here is a sample of the HTML output:

Deep Map coverage

13
votes

Two years after this question originally was posted, there is now remap-istanbul which seems promising.

you can read more about it in Sitepen: Code Coverage for TypeScript and Other Transpiled Languages

As they write in the Github project:

A package that provides the ability to remap Istanbul code coverage information to its original source positions based on a JavaScript Source Maps v3.

As I read the documentation, the project will take your istanbul-generated coverage as input for conversion based on the sourcemap. This sounds like an additional step, but I am sure it will benefit so that you can get rid of those transpiled autogenerated lines in the coverage report.

I believe this is exactly what you will need.

8
votes

Run code coverage against the generated javascript. You can even hit 100% coverage by telling Istanbul to ignore those pesky impossible-to-call lines that typescript writes.

Istanbul honors comments like /* istanbul ignore next */, so what I do is run a string replace in my gulp task that injects the istanbul ignore comments into the auto-generated wrapper code that TypeScript writes.

Here is the gulp task:

var gulp = require('gulp'),
    replace = require('gulp-replace'),
    ts = require('gulp-typescript'),

gulp.task('scripts', function () {
    //compile typescript into javascript
    gulp.src('src/**/*.ts')
        .pipe(ts({
            declarationFiles: false,
            removeComments: false
        }))

        //write comments to tell istanbul to ignore the code inside the iife parameters
        .js.pipe(replace(/(}\)\()(.*\|\|.*;)/g, '$1/* istanbul ignore next */$2'))

        //write comments to tell istanbul to ignore the extends code that typescript generates
        .pipe(replace(/(var __extends = \(this && this.__extends\))/g, '$1/* istanbul ignore next */'))

        //write all of the compiled javascript files to a build folder so we can use them for tests and coverage
        .pipe(gulp.dest('dist/src'))

        //...the rest of your build process
});

Here is the generated code.

var __extends = (this && this.__extends)/* istanbul ignore next */ || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var animalApi;
(function (animalApi) {
    var dogs;
    (function (dogs) {
        var BlackLab = (function (_super) {
            __extends(BlackLab, _super);
            //class code...
        });
        dogs.BlackLab = BlackLab;
    })(/* istanbul ignore next */dogs = animalApi.dogs || (animalApi.dogs = {}));
})(/* istanbul ignore next */animalApi || (animalApi = {}));
7
votes

You can use Chutzpah for that

With Chutzpah you can run your tests from command line and integrate your tests with Visual Studio Test Explorer.

Chutzpah allows you decide if you want to run the tests from .ts files, .js files, .html files or from all of them.

When set (in Visual Studio/Tools/Options/Chutzpah) to run tests from .ts files, you will be able to analyze code coverage of your generated .js files, with a link between the generated JavaScript code and the .ts file that generated it.

It makes really easy to work on your TypeScript code coverage, even being the JavaScript code the real code under test.

You can install Chutzpah from Visual Studio/Tools/Extensions and updates.

You can find here more details about code coverage using Chutzpah.

2
votes

i have created sample to generate code coverage for typescript files using karma coverage and karma typescript processor.

https://github.com/nitinbhatia-dev/karma-typescript-coverage