使用 Angular 4、Webpack 2、Karma 和 Jasmine 获取单元测试覆盖率
Getting unit test coverage working with Angular 4, Webpack 2, Karma, and Jasmine
我有一个使用 Webpack、Angular 4 和 ES6 模块的应用程序。该应用程序按预期工作。
我还使用 Karma 和 Jasmine 设置了单元测试。作为测试设置的一部分,我有一个 test-main.js 如下:
Error.stackTraceLimit = Infinity;
import 'core-js/es6';
import 'core-js/es7/reflect';
import 'reflect-metadata';
import 'zone.js';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/proxy';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import {TestBed} from '@angular/core/testing';
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
let appContext = require.context('./', true, /\.spec\.js/);
appContext.keys().forEach(appContext);
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
单元测试 运行 符合预期。
我正在尝试设置一个覆盖率报告,但我所能达到的最好结果是一个覆盖率报告,其中整个 Webpack 生成的包都在覆盖率报告中进行了检测和报告。正如您想象的那样,这并不完全有用。
我试过使用 babel-plugin-istanbul and also the istanbul-instrumenter-loader 并且我要么在覆盖率报告中得到我的整个捆绑文件,要么根本没有报告。我没有看到任何错误,我的测试继续按预期 运行。
这是我的 karma.conf.js 文件(与覆盖范围有关的所有内容都已删除,因为它不起作用):
// Karma configuration
// Generated on Thu May 04 2017 13:00:28 GMT+0100 (GMT Daylight Time)
'use strict';
const webpack = require('webpack');
const path = require('path');
let reporters = ['progress'],
singleRunSwitch = true,
browsers = ['ChromeHeadless'];
function isDebug(argument) {
return argument === 'debug';
}
if (process.argv.some(isDebug)) {
reporters = ['progress'];
singleRunSwitch = false;
browsers = ['Chrome'];
}
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{ pattern: './test-main.js' }
],
exclude: [],
preprocessors: {
'./test-main.js': ['webpack', 'sourcemap']
},
reporters: reporters,
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: browsers,
customLaunchers: {
ChromeHeadless: {
base: 'Chrome',
flags: [
'--headless',
' --remote-debugging-port=9222',
'--disable-gpu',
'--disable-plugins',
'--window-size=0,0',
'--window-position=-9999,0'
],
},
},
singleRun: singleRunSwitch,
concurrency: Infinity,
webpack: {
module: {
rules: [{
test: /\.js$/,
exclude: path.join(__dirname, '../node_modules/'),
use: [{
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}]
}]
},
devtool: 'inline-source-map',
plugins: [
new webpack.ContextReplacementPlugin(/angular(\|\/)core(\|\/)@angular/, path.join(__dirname))
]
},
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
}
});
}
谁能告诉我需要使用哪些插件以及我应该如何配置它们?
我成功了,我使用了 Istanbul 和 istanbul-instrumenter-loader - 都是通过 NPM 安装的。我的 karma.conf.js 文件现在看起来像这样:
// Karma configuration
// Generated on Thu May 04 2017 13:00:28 GMT+0100 (GMT Daylight Time)
'use strict';
const webpack = require('webpack');
const path = require('path');
let reporters = ['progress', 'coverage'],
singleRunSwitch = true,
browsers = ['ChromeHeadless'];
function isDebug(argument) {
return argument === 'debug';
}
if (process.argv.some(isDebug)) {
reporters = ['progress'];
singleRunSwitch = false;
browsers = ['Chrome'];
}
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{ pattern: './test-main.js' }
],
exclude: [],
preprocessors: {
'./test-main.js': ['webpack', 'sourcemap']
},
reporters: reporters,
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: browsers,
customLaunchers: {
ChromeHeadless: {
base: 'Chrome',
flags: [
'--headless',
'--remote-debugging-port=9222',
'--disable-gpu',
'--disable-plugins',
'--window-size=0,0',
'--window-position=-9999,0'
],
},
},
singleRun: singleRunSwitch,
concurrency: Infinity,
webpack: {
module: {
rules: [{
test: /\.spec.js$/,
exclude: [path.join(__dirname, '../node_modules/'), /\.html$/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015'] }
}]
}, {
test: /\.js$/,
exclude: [path.join(__dirname, '../node_modules/'), /\.spec.js$/, /\.html$/, /test-main.js/],
use: [{
loader: 'istanbul-instrumenter-loader',
}, {
loader: 'babel-loader',
options: { presets: ['es2015'] }
}]
}]
},
devtool: 'inline-source-map',
plugins: [
new webpack.ContextReplacementPlugin(/angular(\|\/)core(\|\/)@angular/, path.join(__dirname))
]
},
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
}
});
}
配置实际上非常简单;我必须添加一个 'coverage' 报告器(但不是在调试时),并且必须添加一个新的 module.rules
Webpack 配置 - 这里实际上有两个配置;我必须通过 Babel 运行 spec 文件与其余的 .js 文件分开,然后将 instanbul-intrumenter 添加到 rules
array for .js files except *.spec.js
(plus排除一堆东西!)
我有一个使用 Webpack、Angular 4 和 ES6 模块的应用程序。该应用程序按预期工作。
我还使用 Karma 和 Jasmine 设置了单元测试。作为测试设置的一部分,我有一个 test-main.js 如下:
Error.stackTraceLimit = Infinity;
import 'core-js/es6';
import 'core-js/es7/reflect';
import 'reflect-metadata';
import 'zone.js';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/proxy';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import {TestBed} from '@angular/core/testing';
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
let appContext = require.context('./', true, /\.spec\.js/);
appContext.keys().forEach(appContext);
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
单元测试 运行 符合预期。
我正在尝试设置一个覆盖率报告,但我所能达到的最好结果是一个覆盖率报告,其中整个 Webpack 生成的包都在覆盖率报告中进行了检测和报告。正如您想象的那样,这并不完全有用。
我试过使用 babel-plugin-istanbul and also the istanbul-instrumenter-loader 并且我要么在覆盖率报告中得到我的整个捆绑文件,要么根本没有报告。我没有看到任何错误,我的测试继续按预期 运行。
这是我的 karma.conf.js 文件(与覆盖范围有关的所有内容都已删除,因为它不起作用):
// Karma configuration
// Generated on Thu May 04 2017 13:00:28 GMT+0100 (GMT Daylight Time)
'use strict';
const webpack = require('webpack');
const path = require('path');
let reporters = ['progress'],
singleRunSwitch = true,
browsers = ['ChromeHeadless'];
function isDebug(argument) {
return argument === 'debug';
}
if (process.argv.some(isDebug)) {
reporters = ['progress'];
singleRunSwitch = false;
browsers = ['Chrome'];
}
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{ pattern: './test-main.js' }
],
exclude: [],
preprocessors: {
'./test-main.js': ['webpack', 'sourcemap']
},
reporters: reporters,
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: browsers,
customLaunchers: {
ChromeHeadless: {
base: 'Chrome',
flags: [
'--headless',
' --remote-debugging-port=9222',
'--disable-gpu',
'--disable-plugins',
'--window-size=0,0',
'--window-position=-9999,0'
],
},
},
singleRun: singleRunSwitch,
concurrency: Infinity,
webpack: {
module: {
rules: [{
test: /\.js$/,
exclude: path.join(__dirname, '../node_modules/'),
use: [{
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}]
}]
},
devtool: 'inline-source-map',
plugins: [
new webpack.ContextReplacementPlugin(/angular(\|\/)core(\|\/)@angular/, path.join(__dirname))
]
},
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
}
});
}
谁能告诉我需要使用哪些插件以及我应该如何配置它们?
我成功了,我使用了 Istanbul 和 istanbul-instrumenter-loader - 都是通过 NPM 安装的。我的 karma.conf.js 文件现在看起来像这样:
// Karma configuration
// Generated on Thu May 04 2017 13:00:28 GMT+0100 (GMT Daylight Time)
'use strict';
const webpack = require('webpack');
const path = require('path');
let reporters = ['progress', 'coverage'],
singleRunSwitch = true,
browsers = ['ChromeHeadless'];
function isDebug(argument) {
return argument === 'debug';
}
if (process.argv.some(isDebug)) {
reporters = ['progress'];
singleRunSwitch = false;
browsers = ['Chrome'];
}
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{ pattern: './test-main.js' }
],
exclude: [],
preprocessors: {
'./test-main.js': ['webpack', 'sourcemap']
},
reporters: reporters,
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: browsers,
customLaunchers: {
ChromeHeadless: {
base: 'Chrome',
flags: [
'--headless',
'--remote-debugging-port=9222',
'--disable-gpu',
'--disable-plugins',
'--window-size=0,0',
'--window-position=-9999,0'
],
},
},
singleRun: singleRunSwitch,
concurrency: Infinity,
webpack: {
module: {
rules: [{
test: /\.spec.js$/,
exclude: [path.join(__dirname, '../node_modules/'), /\.html$/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015'] }
}]
}, {
test: /\.js$/,
exclude: [path.join(__dirname, '../node_modules/'), /\.spec.js$/, /\.html$/, /test-main.js/],
use: [{
loader: 'istanbul-instrumenter-loader',
}, {
loader: 'babel-loader',
options: { presets: ['es2015'] }
}]
}]
},
devtool: 'inline-source-map',
plugins: [
new webpack.ContextReplacementPlugin(/angular(\|\/)core(\|\/)@angular/, path.join(__dirname))
]
},
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
}
});
}
配置实际上非常简单;我必须添加一个 'coverage' 报告器(但不是在调试时),并且必须添加一个新的 module.rules
Webpack 配置 - 这里实际上有两个配置;我必须通过 Babel 运行 spec 文件与其余的 .js 文件分开,然后将 instanbul-intrumenter 添加到 rules
array for .js files except *.spec.js
(plus排除一堆东西!)