dvdzkwsk / react-redux-starter-kit

Get started with React, Redux, and React-Router.
MIT License
10.28k stars 2.2k forks source link

Code coverage generated for wrong files #1308

Open sashafklein opened 7 years ago

sashafklein commented 7 years ago

We've got an app based off the newest Webpack2 version of this starter. It's generally working great, but we're struggling getting code coverage to work. Specifically, as with this closed issue (#1299), coverage isn't reporting for our actual files, but seems to only spit out data about the Webpack config files -- karma.config.js, webpack.config.js and project.config.js, but nothing else!

Here's what we've tried so far:

package.json

    "test": "env NODE_ENV=test nyc --reporter=html node ./node_modules/karma/bin/karma start config/karma.config",

karma.config.js

const argv = require('yargs').argv;
const project = require('../project.config');
// const webpackConfig = require('../build/webpack.config');
const debug = require('debug')('app:config:karma');
const path = require('path');

debug('Creating configuration.');

const webpackConfig = require('../build/webpack.config');

const TEST_BUNDLER = './tests/test-bundler.js';

// Add istanbul instrumenter to webpack rules
webpackConfig.module.rules = webpackConfig.module.rules.concat(
  {
        // delays coverage til after tests are run, fixing transpiled source
        // coverage error
    enforce: 'post',
    test: /\.js$/,
    exclude: /(tests|node_modules|bower_components|build)\//,
    loader: 'istanbul-instrumenter-loader'
  }
);

const karmaConfig = {
  basePath: '../',
  browsers: ['ChromeHeadless'],
  singleRun: !argv.watch,
  coverageReporter: {
    reporters: [
      { type: 'text-summary' },
      'coverage-istanbul'
    ]
  },
  files: [{
    pattern: TEST_BUNDLER,
    watched: false,
    served: true,
    included: true
  }],
  frameworks: ['mocha'],
  preprocessors: {
    [TEST_BUNDLER]: ['webpack']
  },
  logLevel: 'WARN',
  browserConsoleLogOptions: {
    terminal: true,
    format: '%b %T: %m',
    level: ''
  },
  plugins: ['karma-mocha', 'karma-chrome-launcher', 'karma-webpack-with-fast-source-maps', 'karma-coverage-istanbul-reporter'],
  webpack: {
    entry: TEST_BUNDLER,
    devtool: 'cheap-module-source-map',
    module: webpackConfig.module,
    plugins: webpackConfig.plugins,
    resolve: Object.assign({}, webpackConfig.resolve, {
      alias: Object.assign({}, webpackConfig.resolve.alias, {
        sinon: 'sinon/pkg/sinon.js',
        support: path.resolve(project.basePath, 'tests/support/')
      })
    }),
    externals: {
      'react/addons': 'react',
      'react/lib/ExecutionEnvironment': 'react',
      'react/lib/ReactContext': 'react'
    }
  },
  webpackMiddleware: {
    stats: 'errors-only',
    noInfo: true
  },
  coverageIstanbulReporter: {

    // reports can be any that are listed here: https://github.com/istanbuljs/istanbul-reports/tree/590e6b0089f67b723a1fdf57bc7ccc080ff189d7/lib
    reports: ['html', 'text-summary'],

    // base output directory. If you include %browser% in the path it will be replaced with the karma browser name
    dir: path.join(__dirname, 'coverage'),

    // if using webpack and pre-loaders, work around webpack breaking the source path
    fixWebpackSourcePaths: true,

    // stop istanbul outputting messages like `File [${filename}] ignored, nothing could be mapped`
    skipFilesWithNoCoverage: true

    // Most reporters accept additional config options. You can pass these through the `report-config` option
    // 'report-config': {
    //   // all options available at: https://github.com/istanbuljs/istanbul-reports/blob/590e6b0089f67b723a1fdf57bc7ccc080ff189d7/lib/html/index.js#L135-L137
    // }
  }
};

module.exports = (cfg) => cfg.set(karmaConfig);

tests/test-bundler.js

/* eslint no-extend-native:0 */

// ---------------------------------------
// Test Environment Setup
// ---------------------------------------

import React from 'react';
import sinon from 'sinon';
import chai from 'chai';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import chaiEnzyme from 'chai-enzyme';
import { shallow } from 'enzyme';

chai.use(sinonChai);
chai.use(chaiAsPromised);
chai.use(chaiEnzyme());

global.chai = chai;
global.sinon = sinon;
global.expect = chai.expect;
global.should = chai.should();
global.assert = chai.assert;

global.mockComp = (Component, props = {}) => shallow(<Component { ...props } />);

// ---------------------------------------
// Require Tests
// ---------------------------------------
// for use with karma-webpack-with-fast-source-maps
const __karmaWebpackManifest__ = []; // eslint-disable-line
const inManifest = (path) => ~__karmaWebpackManifest__.indexOf(path);

// require all `tests/**/*.spec.js`
const testsContext = require.context('./', true, /\.spec\.js$/);

// only run tests that have changed after the first pass.
const testsToRun = testsContext.keys().filter(inManifest)
;(testsToRun.length ? testsToRun : testsContext.keys()).forEach(testsContext);

// require all `src/**/*.js` except for `main.js` (for isparta coverage reporting)
const componentsContext = require.context('../src/', true, /^((?!main|reducers).)*\.js$/);
componentsContext.keys().forEach(componentsContext);

It successfully creates an HTML file in coverage/index.html which reports the coverage, but again, only for those three config files, not for the actual tests running on our codebase.

Any ideas what we've got wrong here?

Thanks