简体   繁体   English

带有 karma 的覆盖率报告以及 javascript 和 typescript src 文件的混合

[英]Coverage reports with karma and a mix of javascript and typescript src files

I have a project where I use webpack for development/testing and karma as my test runner.我有一个项目,我使用 webpack 进行开发/测试,并使用 karma 作为我的测试运行程序。 This project has source files written half in js and half in ts/tsx.该项目的源文件一半用 js 编写,一半用 ts/tsx 编写。 The test suite is written completely in js.测试套件完全用 js 编写。 I currently use karma-coverage, which shows coverage reports for all my js source files, but it does not support typescript files.我目前使用 karma-coverage,它显示我所有 js 源文件的覆盖率报告,但它不支持打字稿文件。 All my tests run, there is no problem there, I just would like coverage reports for all my test files.我所有的测试都运行,那里没有问题,我只是想要我所有测试文件的覆盖率报告。 Can anyone point me in the right direction?任何人都可以指出我正确的方向吗?

Here is my karma.conf.js if this helps.如果有帮助,这是我的 karma.conf.js。

'use strict';

const webpackCfg = require('./webpack.config')('test');

module.exports = function karmaConfig(config) {

  config.set({
    browsers: ['Chrome'],
    files: [
      'test/loadtests.js'
    ],
    port: 8080,
    captureTimeout: 60000,
    frameworks: [
      'mocha',
      'chai',
      'sinon'
    ],
    client: {
      mocha: {}
    },
    singleRun: true,
    reporters: ['mocha', 'coverage', 'junit'],
    mochaReporter: {
      output: 'autowatch'
    },
    preprocessors: {
      'test/loadtests.js': ['webpack', 'sourcemap']
    },
    webpack: webpackCfg,
    webpackServer: {
      noInfo: true
    },
    junitReporter: {
      outputDir: 'coverage',
      outputFile: 'junit-result.xml',
      useBrowserName: false
    },
    coverageReporter: {
      dir: 'coverage/',
      watermarks: {
        statements: [70, 80],
        functions: [70, 80],
        branches: [70, 80],
        lines: [70, 80]
      },
      reporters: [
        { type: 'text' },
        {
          type: 'html',
          subdir: 'html'
        },
        {
          type: 'cobertura',
          subdir: 'cobertura'
        },
        {
          type: 'lcovonly',
          subdir: 'lcov'
        }
      ]
    }
  });
};

And the relevant part of my webpack test config以及我的 webpack 测试配置的相关部分

  {
      devtool: 'inline-source-map',
      externals: {
        cheerio: 'window',
        'react/lib/ExecutionEnvironment': true,
        'react/addons': true,
        'react/lib/ReactContext': true,
      },
      module: {
        preLoaders: [
          {
            test: /\.(js|jsx)$/,
            loader: 'isparta-loader',
            include: [
              this.srcPathAbsolute
            ]
          }
        ],
        loaders: [
          {
            test: /\.cssmodule\.css$/,
            loaders: [
              'style',
              'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]'
            ]
          },
          {
            test: /^.((?!cssmodule).)*\.css$/,
            loader: 'null-loader'
          },
          {
            test: /\.(sass|scss|less|styl|png|jpg|gif|mp4|ogg|svg|woff|woff2)$/,
            loader: 'null-loader'
          },
          {
            test: /\.json$/,
            loader: 'json'
          },
          {
            test: /\.ts(x?)$/,
            exclude: /node_modules/,
            loader: ['babel', 'ts-loader']
          },
          {
            test: /\.(js|jsx)$/,
            loader: 'babel-loader',
            query: {
              presets: ['airbnb']
            },
            include: [].concat(
              this.includedPackages,
              [
                this.srcPathAbsolute,
                this.testPathAbsolute
              ]
            )
          }
        ]
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': '"test"'
        })
      ]
    }

After a couple days of soul and google searching amongst hundreds of browser tabs, I have found a working solution.经过几天的灵魂和谷歌在数百个浏览器标签中搜索,我找到了一个可行的解决方案。 This is using TypeScript 2.x and Webpack 2.x.这是使用 TypeScript 2.x 和 Webpack 2.x。 test.js is my entry point. test.js是我的切入点。 It could just as easily be test.ts (and it will be eventually).它可以很容易地成为test.ts (最终会如此)。 In that entry point, I load my *.spec.js and *.spec.ts files.在那个入口点,我加载了我的*.spec.js*.spec.ts文件。 And then those files import whichever source they need to test from.然后这些文件导入他们需要测试的任何来源。 I have put all the webpack config in the karma.conf.js so it's easier to see:我已将所有 webpack 配置放在karma.conf.js以便更容易查看:

let myArgs = require('yargs').argv;
let path = require('path');
let webpack = require('webpack');

module.exports = function(config) {
  const REPORTS_PATH = myArgs.reportsPath ? myArgs.reportsPath :path.join(__dirname, 'build');

  config.set({
    basePath: '',

    frameworks: ['jasmine', 'es6-shim'],

    files: [
      './test.js'
    ],

    exclude: [],

    reporters: ['progress', 'spec', 'coverage', 'junit', 'coverage-istanbul'],

    preprocessors: {
      './test.js': ['webpack', 'sourcemap']
    },

    webpackServer: {
       noInfo: true // prevent console spamming when running in Karma!
    },

    webpack: {
      devtool: 'inline-source-map',
      resolve: {
        modules: [
          path.resolve('./node_modules'),
          path.resolve('./')
        ],
        extensions: ['.js', '.ts', '.css', '.scss']
      },
      plugins: [
        new webpack.ProvidePlugin({
           $: "jquery",
           jQuery: "jquery",
          "window.jQuery": "jquery"
        })
      ],
      module: {
        rules: [
          {
            enforce: 'pre',
            test: /\.js$/,
            use: 'source-map-loader',
            exclude: [/node_modules/]
          },
          {
            test: /\.ts$/,
            use: [{
              loader: 'awesome-typescript-loader',
              options: {
                module: 'commonjs'
              },
            }]
          },
          {
            test: /\.js$/,
            use: [{
            loader: 'awesome-typescript-loader',
              options: {
                entryFileIsJs: true,
                transpileOnly: true
              }
            }],
            exclude: [/node_modules/],
          },
          {
            enforce: 'post',
            test: /\.(js|ts)$/,
            use: [{
              loader: 'istanbul-instrumenter-loader',
              options: {
                esModules: true
              }
            }],
            exclude: [/node_modules/, /\.spec\.(js|ts)$/, /test/]
          },
          { test: /\.html/, use: 'raw-loader' },
          { test: /\.(s)?css$/, use: 'null-loader' },
          { test: /\.(png|jpg|jpeg|gif|svg|pdf)$/, use: 'null-loader' },
          { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: 'null-loader' },
          { test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: 'null-loader' },
          { test: /\.json$/, use: 'null-loader' }
        ]
      }
    },

    coverageReporter: {
      type: 'in-memory'
    },

    coverageIstanbulReporter: {
      //TODO: Figure out why the 'html' reporter blows up with istanbul-reports (something with absolute path copying files)
      reports: ['text-summary', 'cobertura'],
      // base output directory
      dir: REPORTS_PATH,
      fixWebpackSourcePaths: true,
      'report-config': {
        cobertura: {
          file: 'coverage.xml'
        },
        'text-summary': {
          file: null
        }
      }
    },

    junitReporter: {
      outputDir: `${REPORTS_PATH}/junit/`,
      outputFile: 'jasmine-results.xml'
    },

    // Hide webpack build information from output
    webpackMiddleware: {
      stats: {
        chunkModules: false,
        colors: true
      },
      noInfo: 'errors-only'
    },

    colors: true,
    logLevel: config.LOG_ERROR,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    autoWatchBatchDelay: 400
  });
};

So, the key pieces here are awesome-typescript-loader , karma-coverage-istanbul-reporter , source-map-loader , and in the tsconfig.json , you want to set these in compilerOptions :所以,这里的关键部分是awesome-typescript-loaderkarma-coverage-istanbul-reportersource-map-loader ,在tsconfig.json ,你想在compilerOptions设置这些:

"inlineSourceMap": true,
"sourceMap": false,

I indicated a TODO about the html report.我指出了关于 html 报告的 TODO。 It DOES work but I couldn't get it to output to a custom directory (subdir) with TypeScript files as a part of it.它确实有效,但我无法将其输出到带有 TypeScript 文件的自定义目录(子目录)作为其中的一部分。 JavaScript only worked fine. JavaScript 只能正常工作。 Could be a windows-specific problem with istanbul-reports .可能是istanbul-reports的特定于 Windows 的问题。 If you add html to the reports array under coverageIstanbulReporter , you should see it in your project dir but may have problems putting it in REPORTS_PATH .如果您将html添加到coverageIstanbulReporter下的reports数组中,您应该会在您的项目目录中看到它,但将其放入REPORTS_PATH可能会出现问题。

It's also worth noting that I had a lot of luck using karma-remap-coverage instead of karma-coverage-istanbul-reporter but the former would not correctly generate cobertura reports for coverage which is what I needed for Jenkins.还值得注意的是,我很幸运地使用karma-remap-coverage而不是karma-coverage-istanbul-reporter但前者无法正确生成 cobertura 报告以进行覆盖,而这正是我对 Jenkins 所需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM