使用 Webpack 的 Karma:伊斯坦布尔覆盖率为 100%(0/0)
Posted
技术标签:
【中文标题】使用 Webpack 的 Karma:伊斯坦布尔覆盖率为 100%(0/0)【英文标题】:Karma with Webpack: Istanbul coverage is 100%(0/0) 【发布时间】:2019-09-03 21:49:36 【问题描述】:我正在尝试使用 Webpack (4.27.1) 和 Karma(3.1.3) + Jasmine(jasmine-core 2.99.1) 为 Angular 1.6.6 应用程序实现代码覆盖功能。所有测试都成功通过。然而,Istanbul(0.4.5) 代码覆盖率结果显示100%(0/0)
测试结果输出
===========覆盖总结============
声明:100% (0/0) 分支:100% (0/0) 功能 : 100% ( 0/0 ) 行数:100% (0/0)
=========================================
HeadlessChrome 73.0.3683 (Windows 7.0.0):执行 128 次中的 127 次(跳过 1 次)成功(15.837 秒 / 14.88 秒) 总计:127 次成功
karma.config.js
const webpackConfig = require('./webpack.config.js');
webpackConfig.devtool = false;
module.exports = function (config)
config.set(
plugins: [
'karma-*'
],
singleRun: true,
frameworks: ['jasmine'],
basePath: '../',
exclude: [],
browsers: ['ChromeHeadless'],
preprocessors:
'test/unit/index_test.js': ['webpack'],
'app/index.js': ['coverage']
,
'reporters': [
'coverage', 'spec', 'html', 'junit'
],
webpack: webpackConfig,
coverageReporter:
dir: 'target/test-results/coverage',
reporters: [
type: 'html', subdir: 'html' ,
type: 'lcovonly', subdir: '.' ,
type: 'text-summary'
],
instrumenterOptions:
istanbul: noCompact: true
,
check:
global:
statements: 90.0,
branches: 80.0,
functions: 80.0,
lines: 90.0
,
reportSlowerThan: 100,
browserNoActivityTimeout: 60000,
autoWatch: true,
files: [
'node_modules/babel-polyfill/dist/polyfill.js',
'test/unit/index_test.js',
]
);
;
webpack.config.js
const webpack = require('webpack');
const path = require('path');
module.exports = merge.smart(base,
entry:
app: './src/app.js'
,
output:
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
,
devtool: 'eval',
devServer: open: true,
module:
rules: [
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
,
]
)
;
.babelrc
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": [
"angularjs-annotate",
"@babel/plugin-transform-modules-commonjs"
],
"env":
"test":
"plugins": ["istanbul"]
index_test.js
import 'core-js/es6/reflect';
import 'core-js/client/shim';
require('app/index');
require('angular');
require('angular-mocks/angular-mocks');
beforeEach(() =>
angular.mock.module('app');
);
const testContext = require.context('.', true, /\.spec.js?$/);
testContext.keys().forEach(testContext);
const srcContext = require.context('../../app/', false, /app\.module\.js$/);
srcContext.keys().forEach(srcContext);
【问题讨论】:
这可能是您的 index_test.js 中的问题,使用path.join(__dirname, '')
就像您在 webpack 配置中所做的那样,真的不确定但试一试。另一个想法将 testContext 中的正则表达式更改为 /\.spec\.js?$/
你错过了一个反斜杠
【参考方案1】:
我们从未设法为我们的 angularjs 项目配置代码覆盖率 istanbul
。这个版本的伊斯坦布尔也已被弃用
我们切换到istanbul-instrumenter-loader
webpack loader
以下配置将为我们生成代码覆盖率
找不到我们遵循的原始指南,但我会尽可能地描述我们的配置
尽我所能:
package.json devDependencies(与代码覆盖率相关)
"babel-loader": "^8.0.5",
"istanbul-instrumenter-loader": "^3.0.1", // webpack loader added in coverage tests
"jasmine-core": "^2.99.1",
"karma": "^3.1.3",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-coverage-istanbul-reporter": "^1.4.2", // coverage reporter used in tests
"karma-html-reporter": "^0.2.7", // html reporter used in tests
"karma-jasmine": "^1.1.1",
"karma-ng-html2js-preprocessor": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^3.0.5",
"webpack": "4.28.4",
测试包版本和你的很接近
package.json 测试脚本:
我们的 karma 配置位于 ./karma
子文件夹中
"scripts":
"test": "NODE_ENV=development karma start karma/karma.conf.js",
"cover": "npm test -- --cover --reportHtml", // pass flags to karma.conf
业力/karma.conf.js
const path = require('path');
const makeWebpackTestConfig = require('./karma.webpack.config');
module.exports = (config) =>
const REPORTS_PATH = path.join(__dirname, '../reports/');
const cover = config.cover || process.env.COVER;
const webstorm = process.env.WEBSTORM; // Running coverage from inside the IDE
const webpack = makeWebpackTestConfig(cover);
const reporters = config.reportHtml ? ['html'] : [];
if (!webstorm) reporters.push('spec');
if (cover) reporters.push('coverage-istanbul');
config.set(
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '../',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: ['src/main.tests.js'],
// list of files to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors:
'src/**/*.js': ['webpack', 'sourcemap'],
'src/**/*.html': ['webpack'],
'src/**/*.less': ['webpack'],
,
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters,
specReporter:
maxLogLines: 5, // limit number of lines logged per test
suppressErrorSummary: false,// do not print error summary
suppressFailed: false, // do not print information about failed tests
suppressPassed: false, // do not print information about passed tests
suppressSkipped: true, // do not print information about skipped tests
showSpecTiming: true, // print the time elapsed for each spec
failFast: false // test would finish with error when a first fail occurs.
,
htmlReporter:
outputDir: path.join(REPORTS_PATH, 'unit-tests'), // where to put the reports
// templatePath: null, // set if you moved jasmine_template.html
focusOnFailures: true, // reports show failures on start
namedFiles: true, // name files instead of creating sub-directories
pageTitle: 'Unit Tests', // page title for reports; browser info by default
urlFriendlyName: true, // simply replaces spaces with _ for files/dirs
reportName: 'index', // report summary filename; browser info by default
// experimental
preserveDescribeNesting: true, // folded suites stay folded
foldAll: true, // reports start folded (only with preserveDescribeNesting)
,
coverageIstanbulReporter:
reports: ['lcov', 'text-summary'],
dir: webstorm ? undefined : path.join(REPORTS_PATH, 'code-coverage'),
,
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN ||
// config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['RunnerHeadless'],
customLaunchers:
RunnerHeadless:
base: 'ChromeHeadless',
flags: ['--headless', '--no-sandbox', '--disable-gpu', '--disable-translate', '--disable-extensions'],
,
,
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
webpack,
webpackMiddleware:
stats: 'errors-only',
,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
client:
// Log browser console only locally
captureConsole: !!process.env.WEBSTORM,
);
;
再次,因为 karma config 位于子文件夹中,路径(base、reports 等)的配置不同。大多数配置是不言自明的。
我们有一个环境变量WEBSTORM
,我们在从IDE 内部运行覆盖时设置它。
还要记住,需要启用源映射才能正确映射到原始源行,因为原始源是由 babel 转换的。
我们正在使用自定义 browsers
配置,您的情况可能不需要此配置
业力/karma.webpack.config.js
const makeWebpackConfig = require('../webpack/base-config');
module.exports = (cover) =>
const defaultConfig = makeWebpackConfig();
// Remove entry. Karma will provide the source
defaultConfig.entry = null;
// Have source maps generated so covered statements are mapped correctly
defaultConfig.devtool = 'inline-source-map';
defaultConfig.mode = 'development';
defaultConfig.optimization =
splitChunks: false,
runtimeChunk: false,
minimize: false,
;
if (cover)
defaultConfig.module.rules.push(
test: /\.js$/,
use:
loader: 'istanbul-instrumenter-loader',
options: esModules: true ,
,
enforce: 'post',
exclude: /node_modules|\.spec\.js$/,
);
return defaultConfig;
;
makeWebpackConfig
创建我们在运行开发或生产构建时使用的基本配置,其中包含 babel-loader
和其他样式、html、文件等加载器...
karma.webpack.conf.js
中覆盖需要覆盖的任何设置
条目已删除,我想,无论如何,Karam 都会覆盖它。
重要 devtool
设置为 inline-source-map
- 事实证明这是一场巨大的斗争,因为似乎外部源映射没有被拾取并且源映射在我们设置为 @987654335 之前不起作用@ 配置。源图不仅有助于代码覆盖,而且在测试失败和打印错误信息时也有帮助——它将引用原始代码行。
最后,在进行覆盖时,将加载程序配置为排除 node_modules 和任何外部源,同时排除测试本身
.babelrc 配置
"presets": [
["@babel/preset-env", "modules": "commonjs" ],
"@babel/preset-react"
],
"plugins": [
"angularjs-annotate",
["@babel/plugin-proposal-decorators",
"legacy": true
],
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
["@babel/plugin-proposal-class-properties",
"loose": true
],
"@babel/plugin-proposal-json-strings",
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions",
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-logical-assignment-operators",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-do-expressions",
"@babel/plugin-proposal-function-bind"
]
应该可以使用您自己的 .babelrc
配置。 "modules": "commonjs"
出于某种原因对我们很重要,但现在不记得了
测试入口点 - src/main.tests.js
import '@babel/polyfill';
import './appConfig';
import './main';
const testsContext = require.context('.', true, /\.spec.js$/);
testsContext.keys().forEach(testsContext);
这与您的配置类似,尽管在 main
和 anglar-mocks
中导入了 angular,因为我们有很多单独的模块,所以每个测试都导入了 anglar-mocks
【讨论】:
以上是关于使用 Webpack 的 Karma:伊斯坦布尔覆盖率为 100%(0/0)的主要内容,如果未能解决你的问题,请参考以下文章
使用 Istanbul + Webpack 覆盖 JSX 文件的代码
Karma + Browserify + Jasmine + 伊斯坦布尔 + React 覆盖