單元測試的代碼覆蓋率統計,是衡量測試用例好壞的一個的方法,有的公司直接把代碼測試覆蓋率做爲一個硬性要求。尤爲在多人合做的狀況下。頗有可能在後期維護時候牽一髮而動全身的代碼修改中起到相當重要的檢測。不過代碼覆蓋率也不是惟一標準,測試用例的好壞主要仍是看能不能覆蓋儘量多的狀況。css
以前代碼覆蓋率在JS代碼不須要編譯的狀況下。直接可使用KARMA的karma-coverage這個工具就能夠直接統計結果。不過因爲個人項目用上了WEBPACK的打包和babel的ES6編譯。因此單單使用karma-coverage統計的代碼覆蓋率統計的是,編譯打包後的代碼,這個覆蓋率直接沒有了參考價值。通常打包後代碼的覆蓋率只有可憐的10%-20%由於WEBPACK幫你加入了不少它的代碼。而測試要作到這些代碼的覆蓋是徹底沒有意義的。因此就須要找一個能夠查看編譯前代碼覆蓋率的一個方法。html
let navbar = angular.module('navbar', []); navbar.controller('navbarCtrl', ['$scope', function ($scope) { $scope.links = ['home', 'about']; }]); module.exports = navbar; //export default navbar;//ES6單元測試支持有問題。因此改用了module.exports = navbar;寫法
import navbar from './navbar.ctrl.js'; describe('navbar', function () { let scope; beforeEach(angular.mock.module('navbar')); beforeEach(angular.mock.inject(function ($rootScope, $controller) { scope = $rootScope.$new(); $controller('navbarCtrl', {$scope: scope}); })); it('Controller測試', function () { expect(scope).to.have.property('links').with.length(2); }); });
而後帶着上面的問題去GITHUB找有沒有人解決過這樣的問題,最後找到了isparta、isparta-instrumenter-loader、istanbul。node
module.exports = function (config) { 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: ['mocha', 'chai'], // list of files / patterns to load in the browser files: ['app/**/*Spec.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: { 'app/**/*Spec.js': ['webpack', 'sourcemap'], 'app/**/*(!Spec).js': ['webpack', 'sourcemap', 'coverage'] }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['mocha', 'coverage'], coverageReporter: { reporters: [ {type: 'text-summary'}, {type: 'html', dir: '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: ['Chrome'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: true, // Concurrency level // how many browser should be started simultaneous concurrency: Infinity, webpack: { devtool: 'inline-source-map', module: { preLoaders: [{ test: /\.js$/, exclude: [/node_modules/,/\.Spec.js$/], loader: 'isparta-instrumenter' }], loaders: [ {test: /\.js$/, exclude: [/node_modules/], loader: 'ng-annotate!babel'}, {test: /\.html/, loader: 'raw'}, {test: /\.styl$/, loader: 'style!css!stylus'}, {test: /\.css$/, loader: 'style!css'} ] } }, webpackServer: { noInfo: true // prevent console spamming when running in Karma! }, plugins: [ 'karma-chrome-launcher', 'karma-chai', 'karma-mocha', 'karma-webpack', 'karma-sourcemap-loader', 'karma-coverage', 'karma-mocha-reporter' ] }) };
以上完成了編譯前代碼覆蓋率的統計。webpack
files: ['app/**/*Spec.js'],
這個主要是導入那些是測試文件。web
preprocessors: { 'app/**/*Spec.js': ['webpack', 'sourcemap'], 'app/**/*(!Spec).js': ['webpack', 'sourcemap', 'coverage'] },
這個是導入前的預處理,由於沒有必要統計測試代碼的覆蓋率,因此測試代碼只須要['webpack', 'sourcemap'],就能夠了。而被測試代碼須要統計覆蓋率,因此須要['webpack', 'sourcemap', 'coverage']。chrome
webpack: { devtool: 'inline-source-map', module: { preLoaders: [{ test: /\.js$/, exclude: [/node_modules/,/\.Spec.js$/], loader: 'isparta-instrumenter' }], loaders: [ {test: /\.js$/, exclude: [/node_modules/], loader: 'ng-annotate!babel'}, {test: /\.html/, loader: 'raw'}, {test: /\.styl$/, loader: 'style!css!stylus'}, {test: /\.css$/, loader: 'style!css'} ] } },
這個KARMA中的webpack配置是最關鍵的。須要在真是WEBPACK打包前用isparta-instrumenter先load一下,記錄編譯前文件。這裏有一個坑。export default navbar;這句話是ES6支持的可是不知道爲何isparta-instrumenter-loader的時候就是編譯有問題。因此只能改爲module.exports = navbar;這樣的寫法。npm