49

I'm having some issues while running Istanbul with Mocha and the Babel compiler.

All my tests are running just fine, but after all the tests done it shows me this message:

No coverage information was collected, exit without writing coverage information

And it is not producing any coverage report.

The command that I am running is:

NODE_ENV=test istanbul cover _mocha -- --require babel-core/register --recursive

The project is hosted on GitHub: https://github.com/weslleyaraujo/react-flux-puzzle/tree/feat/unit-tests-24

Any ideas what it could be?

Yves M.
  • 29,855
  • 23
  • 108
  • 144
Weslley Araujo
  • 668
  • 1
  • 6
  • 18
  • i had this issue recently - you have to follow the flow used by grunt-istanbul I believe which is ... 'instrument', 'mochacli', 'storeCoverage', 'makeReport' (although grunt istanbul is doing it for you in this scenario whereas you are doing it from command line) - so i think you need to 'instrument' your files first - not exactly sure what that means but when i instrument it re-create the files in another dir, and then i think you run mocha against those files - not 100% sure - but definitely instrument first – danday74 Nov 12 '15 at 07:27
  • 1
    @weslley-araujo If you are satisfied by my answer, can you accept it? Thanks. – boneskull Feb 08 '16 at 18:31
  • **istanbul 1.0.0-alpha.2** now allows Babel generated code, see http://stackoverflow.com/a/35976233/1480391 – Yves M. Mar 14 '16 at 21:56

3 Answers3

63

Using Babel 6.x, let's say we have file test/pad.spec.js:

import pad from '../src/assets/js/helpers/pad';
import assert from 'assert';

describe('pad', () => {
  it('should pad a string', () => {
    assert.equal(pad('foo', 4), '0foo');
  });
});

Install a bunch of crap:

$ npm install babel-istanbul babel-cli babel-preset-es2015 mocha

Create a .babelrc:

{
  "presets": ["es2015"]
}

Run the tests:

$ node_modules/.bin/babel-node node_modules/.bin/babel-istanbul cover \   
node_modules/.bin/_mocha -- test/pad.spec.js


  pad
    ✓ should pad a string


  1 passing (8ms)

=============================================================================
Writing coverage object [/Volumes/alien/projects/forked/react-flux-puzzle/coverage/coverage.json]
Writing coverage reports at [/Volumes/alien/projects/forked/react-flux-puzzle/coverage]
=============================================================================

=============================== Coverage summary ===============================
Statements   : 100% ( 4/4 )
Branches     : 66.67% ( 4/6 ), 1 ignored
Functions    : 100% ( 1/1 )
Lines        : 100% ( 3/3 )
================================================================================

UPDATE: I've had success using nyc (which consumes istanbul) instead of istanbul/babel-istanbul. This is somewhat less complicated. To try it:

Install stuff (you can remove babel-istanbul and babel-cli):

$ npm install babel-core babel-preset-es2015 mocha nyc

Create .babelrc as above.

Execute this:

$ node_modules/.bin/nyc --require babel-core/register node_modules/.bin/mocha \ 
test/pad.spec.js

...which should give you similar results. By default, it puts coverage info into .nyc-output/, and prints a nice text summary in the console.

Note: You can remove node_modules/.bin/ from any of these commands when placing the command in package.json's scripts field.

boneskull
  • 1,189
  • 12
  • 11
  • Thanks @boneskull :) It seems that everything is working fine now! after babel update I was getting confused about those new configs.. – Weslley Araujo Nov 16 '15 at 00:29
  • @boneskull Do you have to use babel-node? Is `$ babel-istanbul cover _mocha -- -R spec --compilers js:babel-core/register` not sufficient. Doesn't work for me. – Cameron Feb 06 '16 at 02:54
  • 2
    @cameronjroe Latest istanbul (v0.4.2 at time of this writing) cannot instrument your tests when Mocha's `--compilers` option is used; you must use `babel-node`. From what I can tell, istanbul v1.0.0 should not need `babel-node`. – boneskull Feb 07 '16 at 07:11
  • @boneskull Okay, I'll use `babel-node` for now. Thanks. – Cameron Feb 07 '16 at 19:32
  • 2
    +1 for the `nyc` instructions. I was able to get that going when no magic combo of `babel-istanbul` and related modules could. – Joshua May 30 '16 at 19:21
  • babel lets me specify the present in the cli, is their a way to parse it to babel-core/register when run with mocha? https://babeljs.io/docs/usage/cli/#babel-using-presets i don't want a `.babelrc` file in my root folder – yellowsir Apr 19 '17 at 07:49
  • 2
    I like your 'Install a bunch of crap' approach. You seem to know how development using NPM works in reality. – Nico Van Belle Feb 14 '19 at 15:49
26


PS: I now recommend to use single jest instead of mocha/instanbul/nyc/chai/etc.


Solution A: Using nyc and babel-plugin-istanbul

Setup (don't forget @next for nyc):

npm install --save-dev nyc babel-plugin-istanbul babel-register

Add an env to babel config:

{
  "env": {
    "nyc": { "plugins": ["istanbul"] }
  }
}

nyc config:

{
  "reporter"   : ["text", "text-summary", "lcov", "html"],
  "include"    : ["src/**/*.js"],
  "require"    : ["babel-register"],
  "sourceMap"  : false,
  "instrument" : false,
  "all"        : true
}

PS: include field needs to be specified in .nycrc of in package.json, if specified in command line, coverage will not works

Running the tests:

# 1. Build
NODE_ENV=nyc babel src --out-dir lib

# 2. Coverage
nyc mocha

Solution B: No extra packages : Only the basic ones

Work has been done recently on istanbul (1.0.0-alpha.2) to support Babel generated code with sourcemaps (see #212 and this for an example).

There are 2 ways:

  • A. Tests written against previously transpiled code
  • B. Tests written against original code and transpiled all together in memory at runtime


B1. Tests that exports (previously) transpiled code

This is done in 2 steps: Firstly, build your source with babel (e.g. from ./src to ./out) and write your tests against transpiled source (export foo from "./out/foo";).

Then you will be able to run the tests using istanbul 1.0.0-alpha.2 :

istanbul cover _mocha -- ./test --compilers js:babel-register 

Now if you want code coverage to follow the original code you've written (not the transpiled one), make sure to build with babel source-maps options set to both :

babel ./src --out-dir ./out --source-maps both

PS: If needed you can also do :

istanbul cover _mocha -- ./test --compilers js:babel-register \
   --require babel-polyfill \
   --require should \
   --require sinon


B2. Tests that directly exports original code

In this case you write your tests against original source (export foo from "./src/foo";), and with no further step, you directly run istanbul 1.0.0-alpha.2 using babel-node against cli.js :

babel-node ./node_modules/istanbul/lib/cli.js cover _mocha -- ./test

PS: If needed you can also do :

babel-node ./node_modules/istanbul/lib/cli.js cover _mocha -- ./test
   --require babel-polyfill \
   --require should \
   --require sinon
Yves M.
  • 29,855
  • 23
  • 108
  • 144
  • 1
    Perfect, thanks! I had to use slightly different syntax: `istanbul cover node_modules/mocha/bin/_mocha -- ./test --compilers js:babel-core/register` – Pier-Luc Gendreau Mar 14 '16 at 18:29
  • Yep, upgrading to the alpha version does take care of problems with babel and Mocha. However, the resulting report cannot be combined with reports produced through `karma-coverage` which uses istanbul 0.4.x. – Louis May 25 '16 at 00:28
  • 1
    I've found switching to `nyc` extremely straightforward - just install, provide the source tree and extensions and it worked out of the box with pretty complex tech stack. Wonder if it could be that simple for `jest` as well? Maybe you know some documentation? – ciekawy Jun 21 '17 at 23:16
4

As of now 17.4.2016 this coverage reporting stuff is still a bit messy and with my React-project that has .jsx files and a helper file the coverage reporting script looks like this:

istanbul cover node_modules/mocha/bin/_mocha -- \
   --compilers js:babel-core/register \
   --require ./test/testhelper.js  \
   \"test/**/*@(.js|.jsx)\"

So it wouldn't be too easy the current version 0.4.3 of Istanbul doesn't work with Babel so you have to use the experimental alpha-version:

npm install istanbul@1.0.0-alpha.2 --save-dev

And then you need .istanbul.yml -file so that Istanbul recognizes the .jsx-files with these lines:

instrumentation:
  root: .
  extensions: ['.js', '.jsx']

And now it should work. Also as a small bonus if you want to add coverage reporting with Travis and Coveralls you should:

  1. enable the project in https://coveralls.io
  2. add coveralls npm i coveralls --save-dev
  3. add this to your .travis.yml:

    script:
      - npm --silent test
      - cat ./c
    coverage/lcov.info | coveralls
    

And now you can put that cool badge to your README. Neato!

Yves M.
  • 29,855
  • 23
  • 108
  • 144
TeemuK
  • 2,095
  • 1
  • 18
  • 17
  • Yep, upgrading to the alpha version does take care of problems with babel and Mocha. However, the resulting report cannot be combined with reports produced through `karma-coverage` which uses istanbul 0.4.x. – Louis May 25 '16 at 00:27