Sourcemap + istanbul/isparta 代码覆盖 webpack + babel (for es6) + mocha (+karma)

Posted

技术标签:

【中文标题】Sourcemap + istanbul/isparta 代码覆盖 webpack + babel (for es6) + mocha (+karma)【英文标题】:Sourcemap + istanbul/isparta code coverage for a webpack + babel (for es6) + mocha (+karma) 【发布时间】:2016-06-02 16:39:24 【问题描述】:

我在https://github.com/danielbush/webpack-babel-karma-sourcemap-coverage 有一个测试项目。

它包含src/ 中的两个简单源文件,其中一个包含故意错误 (src/lib2.js)。

我想使用 babel 从 ES6 到 ES5 进行 webpack 和转译,并使用 Karma 在这个包上运行 Mocha 测试。

我已经添加了源映射并对此进行了测试,以便可以看到原始文件的行号。

对我来说,堆栈跟踪如下所示:

21 02 2016 16:03:15.445:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
21 02 2016 16:03:15.451:INFO [launcher]: Starting browser Chrome
21 02 2016 16:03:16.551:INFO [Chrome 48.0.2564 (Linux 0.0.0)]: Connected on socket /#yRS32ons0_2HGhrwAAAA with id 3072946

START:
  lib1
    ✖ should return 1

Finished in 0.015 secs / 0.001 secs

SUMMARY:
✔ 0 tests completed
✖ 1 test failed

FAILED TESTS:
  lib1
    ✖ should return 1
      Chrome 48.0.2564 (Linux 0.0.0)
    Error: SIMULATED ERROR
        at foo (/home/danb/projects/so-test-project/tests.webpack.js:135:10 <- webpack:///src/lib2.js:13:8)
        at Context.<anonymous> (/home/danb/projects/so-test-project/tests.webpack.js:93:31 <- webpack:///test/index.js:7:11)

在上面的最后第二行,它显示webpack:///src/lib2.js:13,这是原始源中的正确位置。

为了获得该映射,我这样做了:https://github.com/danielbush/webpack-babel-karma-sourcemap-coverage/commit/6ea992cae499dccc68488bcb3eaca642ae4ed24e

我想要做的是使用诸如 istanbul(或使用 istanbul 的 isparta)之类的东西添加覆盖率,以便我可以在 coverage/ 中生成 html 覆盖率报告,显示未覆盖的行(可能)——以及作为整体覆盖率。

但我想确保我的堆栈跟踪仍然像上面那样正确映射源。

我已经尝试使用 isparta-loader 和 isparta-instrumenter-loader 在 webpack 中转译和检测有问题的文件,但我的行号在堆栈跟踪(上图)中略有错误。似乎有许多类似 isparta 的东西在四处飘荡,文档也不是超级友好。

更一般地表达所有这些:我正在捆绑文件和测试,然后在浏览器中测试它(业力或通过更多手动方式),我希望我的源映射(在浏览器中)指向原始代码行和同时我想要一份覆盖率报告来引用未被覆盖的原始行和文件。

【问题讨论】:

【参考方案1】:

我没有针对单个 karma/webpack 配置的解决方案。我的解决方法是拥有 2 个 karma confs - 我对 atm 非常满意。 (我还有其他用于运行测试的非业力设置。)

一个 conf 在后台运行测试,并为我的 es6 代码提供准确的堆栈跟踪,另一个使用 isparta-loader 运行覆盖以转译和检测我的源代码。 (isparta-loader 使用 isparta,它使用伊斯坦布尔)。

所以我的“运行测试”karma conf 看起来有点像这样:

var webpack = require('webpack');
module.exports = function (config) 
  config.set(
    browsers: [ 'PhantomJS' ],
    singleRun: false,
    frameworks: [ 'mocha' ], // Use the mocha test framework
    files: [
      'tests.webpack.js'
    ],
    preprocessors: 
      'tests.webpack.js': [ 'webpack', 'sourcemap' ]
    ,
    reporters: [ 'mocha' ],
    webpack: 
      devtool: 'inline-source-map',
      module: 
        loaders: [
          // Use imports loader to hack webpacking sinon.
          // https://github.com/webpack/webpack/issues/177
          
            test: /sinon\.js/,
            loader: "imports?define=>false,require=>false"
          ,
          
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query:  presets: ['es2015'] 
          
        ]
      
    ,
    webpackServer: 
      noInfo: true
    
  );

而我的覆盖 karma conf 看起来有点像这样:

var webpack = require('webpack'),
    path = require('path');
module.exports = function (config) 
  config.set(
    browsers: [ 'PhantomJS' ],
    singleRun: true,
    frameworks: [ 'mocha' ],
    files: [
      'tests.webpack.js'
    ],
    preprocessors: 
      'tests.webpack.js': [ 'webpack' ]
    ,
    reporters: [ 'coverage' ],
    webpack: 
      // *optional* babel options: isparta will use it as well as babel-loader
      babel: 
        presets: ['es2015']
      ,
      // *optional* isparta options: istanbul behind isparta will use it
      isparta: 
        embedSource: true,
        noAutoWrap: true,
        // these babel options will be passed only to isparta and not to babel-loader
        babel: 
          presets: ['es2015']
        
      ,
      module: 
        loaders: [
          
            test: /sinon\.js/,
            loader: "imports?define=>false,require=>false"
          ,
          // Perform babel transpiling on all non-source, test files.
          
            test: /\.js$/,
            exclude: [
              path.resolve('node_modules/'),
              path.resolve('lib/')
            ],
            loader: 'babel-loader',
            query:  presets: ['es2015'] 
          ,
          // Instrument source files with isparta-loader (will perform babel transpiling).
          
            test: /\.js$/,
            include: [
              path.resolve('lib/')
            ],
            loader: 'isparta'
          
        ]
      
    ,
    webpackServer: 
      noInfo: true
    ,
    coverageReporter: 
      reporters: [
         type: 'html', dir: 'coverage/' ,
         type: 'text' 
      ]
    
  );

第二次会议提供了一个文本报告,可以在终端中提供即时覆盖率摘要,以及 html 报告,它可以很好地突出显示未经测试的代码的源文件。 (对于 sinon 都有一个 hack,与这个问题无关。)tests.webpack.js 使用 webpack 的 require.context 来提取我用 mocha 编写的浏览器测试。并且需要各种 karma-* 插件。

【讨论】:

您是否获得了“原始”es6 文件的覆盖率 html 输出?我的设置(与您的非常相似)输出“错误”的 es6 覆盖率报告。弄乱红/绿线等。【参考方案2】:

使用伊斯坦布尔的新 official Babel Plugin 来检测您的源代码覆盖率可能会更好。

根据我的经验,与isparta 相比,它提供了更准确的覆盖率报告,除了将其添加到我的 Babel 配置中的插件列表之外,基本上不需要任何配置。

当我在我的项目中使用 Sourcemaps 时,它似乎“开箱即用”正常工作。

【讨论】:

以上是关于Sourcemap + istanbul/isparta 代码覆盖 webpack + babel (for es6) + mocha (+karma)的主要内容,如果未能解决你的问题,请参考以下文章

sourcemap详解

Webpack中的sourcemap

GENERATE_SOURCEMAP=false 问题

如果在 Angular 中将 sourcemap 设置为 false 会发生啥

sourcemap文件泄露漏洞

弄懂 SourceMap,前端开发提效 100%