我目前正在与茉莉花因果赛跑者进行单元测试。我使用Web Pack作为包装经理。我认为这是一个配置问题,由于该问题我无法获得覆盖率结果,因此它在所有覆盖率上始终显示0/0,我在angular 4.4版本中工作,不建议更新此版本。
我已经尝试过伊斯坦布尔报告的覆盖率和业障覆盖率,以获取覆盖率结果。
Karma.conf
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'./config/env.test.js',
{ pattern: './spec-bundle.js', watched: false },
],
preprocessors: {
'./spec-bundle.js': ['webpack']
},
webpack: require('./webpack.config')({app: 'projectName', mode: 'test'}),
webpackMiddleware: {
noInfo: true
},
reporters: ['progress', 'coverage-istanbul'],
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly'],
dir: 'coverage/',
fixWebpackSourcePaths: true,
combineBrowserReports: true,
skipFilesWithNoCoverage: true,
'report-config': {
html: {
subdir: 'html'
}
},
thresholds: {
emitWarning: false,
global: {
statements: 100,
lines: 100,
branches: 100,
functions: 100
}
}
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: [ 'Chrome'],
// browsers: [ 'PhantomJS'],
singleRun: false,
client: {
clearContext: false
},
concurrency: Infinity,
verbose: true
});
}
spec.bundle.js
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
const testing = require('@angular/core/testing');
const browser = require('@angular/platform-browser-dynamic/testing');
beforeAll(() => {
testing.TestBed.resetTestEnvironment();
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule,
browser.platformBrowserDynamicTesting());
});
const context = require.context("./src/test", true, /\.spec\.ts$/);
context.keys().map(context);
function requireAll(requireContext) {
return requireContext.keys().map(requireContext);
}
const modules = requireAll(context)
webpack.conf.js
const path = require('path');
const helpers = require('./node.helpers.js');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
NoEmitOnErrorsPlugin,
SourceMapDevToolPlugin
} = require('webpack');
const {
NamedLazyChunksWebpackPlugin,
BaseHrefWebpackPlugin
} = require('@angular/cli/plugins/webpack');
const { AotPlugin } = require('@ngtools/webpack');
const entryPoints = [
'inline',
'polyfills',
'sw-register',
'styles',
'vendor',
'main'
];
module.exports = function(environment) {
const tsConfig = environment.mode === 'test' ? 'src\\tsconfig.spec.json' : 'src\\tsconfig.app.json';
console.log('+++++++tsConfigPath++++++++++++',tsConfig);
var CONFIG = {
stats: 'errors-only',
resolve: {
extensions: ['.ts', '.js', '.scss'],
modules: ['./node_modules', './node_modules'],
symlinks: true
},
resolveLoader: {
modules: [
'./node_modules',
'./node_modules',
path.resolve(__dirname, 'loaders')
]
},
entry: {
polyfills: ['./src/polyfills.ts']
//styles: ['./src/styles.css']
},
output: {
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js'
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
exclude: [/(\\|\/)node_modules(\\|\/)/]
},
{
test: /\.html$/,
loader: 'raw-loader'
},
{
test: /\.(eot|svg|cur)$/,
loader: 'file-loader',
options: {
name: '[name].[hash:20].[ext]',
limit: 10000
}
},
{
test: /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
loader: 'url-loader',
options: {
name: '[name].[hash:20]',
limit: 10000
}
},
{
test: /.[s]*css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: () => [require('autoprefixer')]
}
},
'resolve-url-loader',
'sass-loader?sourceMap',
{
loader: 'dls-loader',
options: require('./dls-config.json')
}
]
},
{
test: /\.ts$/,
loader: '@ngtools/webpack'
},
{
enforce: 'post',
test: /\.(js|ts)$/,
loader: 'istanbul-instrumenter-loader',
query: {
esModules: true
},
include: helpers.root('src'),
exclude: [/\.(e2e|spec)\.ts$/, /node_modules/]
}
]
},
plugins: [
new NoEmitOnErrorsPlugin(),
new CopyWebpackPlugin(
[
{
context: 'src',
to: '',
from: {
glob: './assets/**/*',
dot: true
}
},
{
context: 'src',
to: '',
from: {
glob: './favicon.ico',
dot: true
}
}
],
{
ignore: ['.gitkeep'],
debug: 'warning'
}
),
new CopyWebpackPlugin([
{
from: `./config/env.${environment.mode}.js`,
to: './env.js',
toType: 'file'
},
{
from: './launcherClient/phoenixlauncher.js',
to: './phoenixlauncher.js',
toType: 'file'
},
{
from: './launcherClient/preLaunchingApp.html',
to: './preLaunchingApp.html',
toType: 'file'
},
{
from: './launcherClient/libs/jquery-3.3.1.min.js',
to: './libs/jquery-3.3.1.min.js',
toType: 'file'
},
{
from: './help/**/*',
to : './',
}
]),
new ProgressPlugin(),
new CircularDependencyPlugin({
exclude: /(\\|\/)node_modules(\\|\/)/,
failOnError: false
}),
new NamedLazyChunksWebpackPlugin(),
new BaseHrefWebpackPlugin({}),
new SourceMapDevToolPlugin({
filename: '[file].map[query]',
moduleFilenameTemplate: '[resource-path]',
fallbackModuleFilenameTemplate: '[resource-path]?[hash]',
sourceRoot: 'webpack:///'
}),
],
node: {
fs: 'empty',
global: true,
crypto: 'empty',
tls: 'empty',
net: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
},
devServer: {
historyApiFallback: true
}
};
// Below configurations are separated because to ease th import of projectName app webpack conf to another webapack configuration.
CONFIG.entry.main = ['./src/projectName/main.ts'];
CONFIG.output.path = path.join(process.cwd(), '/dist/projectName');
CONFIG.plugins.push(
new HtmlWebpackPlugin({
template: './src/projectName/index.html',
filename: './index.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: [],
title: 'Webpack App',
xhtml: true,
chunksSortMode: function sort(left, right) {
let leftIndex = entryPoints.indexOf(left.names[0]);
let rightindex = entryPoints.indexOf(right.names[0]);
if (leftIndex > rightindex) {
return 1;
} else if (leftIndex < rightindex) {
return -1;
} else {
return 0;
}
}
})
);
CONFIG.plugins.push(
new AotPlugin({
mainPath: './projectName/main.ts',
replaceExport: false,
hostReplacementPaths: {
'environments\\environment.ts': 'environments\\environment.ts'
},
exclude: [],
tsConfigPath: tsConfig,
skipCodeGeneration: true
})
);
return CONFIG;
};
我需要获取coverage文件夹中的coverage百分比。