Package Exports
- babel-plugin-__coverage__
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (babel-plugin-__coverage__) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
babel-plugin-__coverage__
A Babel plugin that instruments your code with __coverage__ variable.
The resulting __coverage__ object is compatible with Istanbul.
Note: This plugin does not generate any report or save any data to any file; it only adds instrumenting code to your JavaScript source code. To integrate with testing tools, please see the Integrations section.
Usage
Install it:
npm install --save-dev babel-plugin-__coverage__Add it to .babelrc in test mode:
{
"env": {
"test": {
"plugins": [ "__coverage__" ]
}
}
}Integrations
karma
It just works with Karma. First, make sure that the code is already transpiled by Babel (either using karma-babel-preprocessor, karma-webpack, or karma-browserify). Then, simply set up karma-coverage according to the docs, but don’t add the coverage preprocessor. This plugin has already instrumented your code, and Karma should pick it up automatically.
It has been tested with bemusic/bemuse project, which contains ~2400 statements.
node.js (using nyc)
Configure Mocha to transpile JavaScript code using Babel, then you can run your tests with nyc, which will collect all the coverage report. You need to configure NYC not to instrument your code by adding setting this in your package.json:
"nyc": {
"include": [ "/" ]
},Canned Answers
There’s already Isparta. Why another coverage tool?
Isparta is the de-facto tool for measuring coverage against ES6 code, which extends Istanbul with ES6 support. But it did not go that smoothly.
So I’ve been trying to get webpack 2 to work with Istanbul/Isparta.
To benefit from webpack 2’s with tree shaking, I need to keep import and export statements in JavaScript file intact. I can’t get code coverage to work. Inspecting Isparta’s source code, here’s what it does:
- It uses Babel to transpile ES6 back into ES5, saving the source map.
- It uses Istanbul to instrument the transpiled source code. This produces some initial metadata (in a global variable called
__coverage__) which contains the location of each statement, branch, and function. Unfortunately, the location is mapped to the transpiled code. Therefore, - The metadata is processed using source map obtained from step 1 to map the location in transpiled code back to the location in the original source code.
- The final instrumented code in ES5 is generated. This code shouldn’t be processed through Babel again, or it will be redundant and leads to slower builds.
Since transforming import/export statements has now been disabled, instrumentation now dies at step 2.
So I looked for something else, and I found babel-plugin-transform-adana. I tried it out immediately.
It turns out that although adana also generates the __coverage__ variable, it is in its own format. This means that most tools that works with Istanbul-format coverage data (including karma-coverage and nyc) will not work with this. Tools need to be reinvented for each test harness.
Now, with lots of tools to help developers author Babel 6 plugins, such as the Babel Handbook and the AST Explorer, it’s not that hard to create Babel plugins today. So I gave it a shot. This is my first Babel plugin.
It turns out that I can create a rudimentary instrumenter with Babel 6 in roughly 300 lines of code (compare to 1,000 in Istanbul). Babel has A LOT of cool stuff to make transpilation easy, from babel-template to babel-traverse to babel-helper-function-name. Babel’s convenient API also handles a lot of edge cases automatically. For example, if a function begins with 'use strict' statement, prepending a statement into its body will insert it after the 'use strict' statement. It also automatically convert if/while/for body into a BlockStatement when a statement is inserted before the body.
Is it stable?
Well, I wrote most of it in two nights and have only tested some basic stuffs. So speaking in terms of maturity, this one is very new.
However, I tried using them in some bigger projects, such as bemusic/bemuse (contains around 2400 statements) without much problem, and it works fine.
How do I ignore branches/statements?
I haven’t implemented it. I once posted an issue on Isparta asking about ignoring statements in Isparta (which is now fixed). But later, I just think that “coverage is just a number.” Also, I don’t have time to implement it.
Pull requests are welcome!
How do I ignore certain files?
Well, Codecov allows you to ignore files from their web interface, so if you’re using that, then that’s the easiest way!
Oh yeah if you use webpack, you can set up two loaders. One for your production code (with this plugin enabled), and another for your test code (without this plugin).
And if you’re using Babel, you can precompile your production code with coverage enabled into another directory like babel src --plugins __coverage__ -d lib-cov and tell your tests to redirect to that instead.
But if you’re using something like browserify or babel-register where you can only enable or disable this plugin for every source file, then sorry, I haven’t implemented it yet, because I don’t need it now. If you want it, pull requests are welcome!