运行 Mocha + Istanbul + Babel

49

我在使用Mocha和Babel编译器运行Istanbul时遇到了一些问题。

我的所有测试都正常运行,但是在所有测试完成后,它会显示给我这个消息:

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

同时它没有生成任何覆盖率报告。

我正在运行的命令是:

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

该项目托管在GitHub上:https://github.com/weslleyaraujo/react-flux-puzzle/tree/feat/unit-tests-24

有什么想法吗?


最近我遇到了这个问题 - 我认为你必须遵循 grunt-istanbul 使用的流程,即... 'instrument'、'mochacli'、'storeCoverage'、'makeReport'(尽管在这种情况下 grunt istanbul 为您执行此操作,而您是从命令行执行此操作) - 所以我认为您需要首先对文件进行'instrument'处理 - 不太确定这意味着什么,但当我对其进行'instrument'处理时,它会在另一个目录中重新创建文件,然后我认为您可以针对这些文件运行 mocha - 不是100%确定 - 但一定要先进行'instrument'处理。 - danday74
1
@weslley-araujo 如果您对我的回答感到满意,可以接受它吗?谢谢。 - boneskull
istanbul 1.0.0-alpha.2 现在支持 Babel 生成的代码,详见 https://dev59.com/-FwX5IYBdhLWcg3wlwaQ#35976233。 - Yves M.
3个回答

63

使用 Babel 6.x,假设我们有文件 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');
  });
});

安装一大堆垃圾软件:

$ npm install babel-istanbul babel-cli babel-preset-es2015 mocha
创建一个.babelrc文件:
{
  "presets": ["es2015"]
}

运行测试:

$ 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 )
================================================================================

更新: 我已经成功地使用nyc(它使用istanbul)代替istanbul/babel-istanbul。这种方式更加简单。尝试一下:

安装相关软件(你可以删除babel-istanbulbabel-cli):

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

按照上述创建.babelrc

执行以下内容:

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

...这应该会给你类似的结果。默认情况下,它将覆盖信息放入.nyc-output/中,并在控制台中打印一个漂亮的文本摘要。

注意: 当将命令放在package.jsonscripts字段中时,可以从任何这些命令中删除node_modules/.bin/


谢谢@boneskull :)现在似乎一切都正常了!在babel更新后,我对那些新配置感到困惑。 - Weslley Araujo
2
@cameronjroe 最新的 Istanbul(在撰写本文时为v0.4.2)无法在使用 Mocha 的 --compilers 选项时对您的测试进行仪器化;您必须使用 babel-node。据我所知,Istanbul v1.0.0 不需要 babel-node - boneskull
2
+1 给 nyc 指令。当没有任何神奇的 babel-istanbul 和相关模块可以运行时,我能够让它正常工作。 - Joshua
Babel 允许我在 CLI 中指定 present,有没有办法在使用 Mocha 运行时将其解析到 babel-core/register 中?https://babeljs.io/docs/usage/cli/#babel-using-presets 我不想在根目录中放置 .babelrc 文件。 - yellowsir
2
我喜欢你的“安装一堆垃圾”的方法。你似乎知道如何在实际开发中使用NPM。 - Nico Van Belle
显示剩余2条评论

26
PS:我现在推荐使用单个jest,而不是mocha/instanbul/nyc/chai等。
方案A:使用nycbabel-plugin-istanbul 设置(不要忘记为nyc添加@next):
npm install --save-dev nyc babel-plugin-istanbul babel-register

将一个环境添加到babel配置中:
{
  "env": {
    "nyc": { "plugins": ["istanbul"] }
  }
}

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

PS:include字段需要在.nycrcpackage.json中指定,如果在命令行中指定,则覆盖率将不起作用。
运行测试:
# 1. Build
NODE_ENV=nyc babel src --out-dir lib

# 2. Coverage
nyc mocha

解决方案B:不需要额外的包,只使用基本的包
最近在伊斯坦布尔(1.0.0-alpha.2)上进行了工作,以支持使用sourcemaps生成的Babel代码(请参见#212this的示例)。
有两种方式:
  • A. 对先前转换过的代码编写测试
  • B. 编写针对原始代码的测试,并在运行时将所有代码一起转换


B1. 测试导出(之前已经)转译的代码

这需要分两步完成:首先,使用babel构建你的源代码(例如从./src到./out),并针对转译后的源代码编写测试(export foo from "./out/foo";)。

然后,您将能够使用istanbul 1.0.0-alpha.2 运行测试:

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

如果您想让代码覆盖率跟随您编写的原始代码(而不是转换后的代码),请确保使用 babel source-maps options 设置为both 进行构建:
babel ./src --out-dir ./out --source-maps both

PS:如果需要,您也可以执行以下操作:

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


B2. 直接导出原始代码的测试

在这种情况下,您会针对原始源代码(export foo from "./src/foo";)编写测试,并且不需要进一步的步骤,您可以直接使用babel-node运行istanbul 1.0.0-alpha.2来执行cli.js:

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

PS:如果需要,您还可以执行以下操作:
babel-node ./node_modules/istanbul/lib/cli.js cover _mocha -- ./test
   --require babel-polyfill \
   --require should \
   --require sinon

1
太好了,谢谢!我必须使用略有不同的语法:istanbul cover node_modules/mocha/bin/_mocha -- ./test --compilers js:babel-core/register - Pier-Luc Gendreau
是的,升级到alpha版本确实解决了babel和Mocha的问题。然而,由此产生的报告无法与通过使用istanbul 0.4.x的karma-coverage生成的报告合并。 - Louis
1
我发现切换到 nyc 非常简单 - 只需安装,提供源代码树和扩展即可,它可以与相当复杂的技术堆栈开箱即用。不知道对于 jest 是否也能这么简单?也许你知道一些相关文档? - ciekawy

4

截至2016年4月17日,这种覆盖率报告的东西仍然有点混乱。对于我的React项目,其中包括.jsx文件和一个辅助文件,覆盖率报告脚本如下:

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

因此,目前版本的Istanbul 0.4.3不能与Babel一起使用,所以您必须使用实验性的alpha版本:

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

然后您需要一个.istanbul.yml文件,这样Istanbul才能识别这些行的.jsx文件:

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

现在应该可以工作了。如果您想使用Travis和Coveralls添加覆盖率报告,则应执行以下操作:

  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
    

现在,您可以将这个很酷的标记加入到您的 README 文件中。真不错!


是的,升级到 alpha 版本确实解决了 babel 和 Mocha 的问题。然而,生成的报告无法与使用 istanbul 0.4.x 的 karma-coverage 生成的报告合并。 - Louis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接