使用 Karma、Angular 和 Husky 执行代码覆盖率

Code Coverage Enforcement with Karma, Angular and Husky

目前,我正在尝试通过 angular-cli 的选项建立代码覆盖率实施,即在 coverageIstanbulReporter 中使用 thresholds 对象。我正在使用 git 挂钩 运行 ng test --single-run --code-coverage。不幸的是,80threshold 值未被遵守。

我指的是这个:Code Coverage Enforcement

这是我的karma.conf.js

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-firefox-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('karma-spec-reporter'),
      require('@angular/cli/plugins/karma')
    ],
    client:{
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    files: [
      { pattern: './src/test.ts', watched: false }
    ],
    preprocessors: {
      './src/test.ts': ['@angular/cli']
    },
    mime: {
      'text/x-typescript': ['ts', 'tsx']
    },
    coverageIstanbulReporter: {
      reports: ['html', 'lcovonly', 'text-summary'],
      fixWebpackSourcePaths: true,
      thresholds: {
        statements: 80,
        lines: 80,
        branches: 80,
        functions: 80
      }
    },
    angularCli: {
      environment: 'dev'
    },
    reporters: config.angularCli && config.angularCli.codeCoverage
      ? ['spec', 'coverage-istanbul']
      : ['spec', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};

========= 最终解决方案 =========
最后的package.json

{
  "name": "ng-fun",
  "version": "0.0.1",
  "license": "",
  "scripts": {
    "precommit": "ng lint",
    "prepush": "ng test --code-coverage --single-run",
    "clean": "rimraf node_modules dist coverage",
    "clean:dist": "rimraf dist",
    "clean:install": "npm run clean && npm install",
    "ng": "ng",
    "start": "ng serve",
    "build:dev": "ng build",
    "build:prod": "ng build -prod",
    "test": "ng test",
    "test:coverage": "ng test --code-coverage",
    "test:sr:coverage": "ng test --single-run --code-coverage",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "4.0.3",
    "@angular/common": "4.0.3",
    "@angular/compiler": "4.0.3",
    "@angular/core": "4.0.3",
    "@angular/forms": "4.0.3",
    "@angular/http": "4.0.3",
    "@angular/platform-browser": "4.0.3",
    "@angular/platform-browser-dynamic": "4.0.3",
    "@angular/router": "4.0.3",
    "@ngrx/core": "1.2.0",
    "@ngrx/router-store": "1.2.6",
    "@ngrx/store": "2.2.2",
    "@ngrx/store-devtools": "3.2.4",
    "core-js": "2.4.1",
    "immutable": "3.8.1",
    "reset-css": "2.2.0",
    "rxjs": "5.3.0",
    "web-animations-js": "2.2.5",
    "zone.js": "0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.0.1",
    "@angular/compiler-cli": "4.0.3",
    "@types/jasmine": "2.5.38",
    "@types/node": "6.0.60",
    "codelyzer": "2.0.0",
    "husky": "0.13.3",
    "jasmine-core": "2.5.2",
    "jasmine-spec-reporter": "3.2.0",
    "karma": "1.4.1",
    "karma-chrome-launcher": "2.0.0",
    "karma-cli": "1.0.1",
    "karma-coverage-istanbul-reporter": "1.2.0",
    "karma-firefox-launcher": "1.0.1",
    "karma-jasmine": "1.1.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "karma-spec-reporter": "0.0.31",
    "protractor": "5.1.0",
    "rimraf": "2.6.1",
    "ts-node": "2.0.0",
    "tslint": "4.5.0",
    "typescript": "2.2.2"
  }
}

决赛karma.conf.js

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-firefox-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('karma-spec-reporter'),
      require('@angular/cli/plugins/karma')
    ],
    client:{
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    files: [
      { pattern: './src/test.ts', watched: false }
    ],
    preprocessors: {
      './src/test.ts': ['@angular/cli']
    },
    mime: {
      'text/x-typescript': ['ts', 'tsx']
    },
    coverageIstanbulReporter: {
      reports: ['html', 'text-summary', 'json-summary'],
      fixWebpackSourcePaths: true,
      thresholds: {
        global: { // thresholds for all files
          statements: 60,
          lines: 60,
          branches: 60,
          functions: 60
        },
        each: { // thresholds per file
          statements: 60,
          lines: 60,
          branches: 60,
          functions: 60
        }
      }
    },
    angularCli: {
      environment: 'dev'
    },
    reporters: config.angularCli && config.angularCli.codeCoverage
      ? ['progress', 'spec', 'coverage-istanbul']
      : ['progress', 'spec', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome', 'Firefox'],
    singleRun: false
  });
};

据此:https://github.com/mattlewis92/karma-coverage-istanbul-reporter/blob/master/CHANGELOG.md。 threshold 是在版本 0.3.0 中引入的,我相信 angular-cli v1.0.0 将版本 0.2.0 添加到你的 package.json

所以: 1. 确保你的 package.json 中有 karma-coverage-istanbul-reporter 的 0.3.0 或更高版本 2. 使用 threshold 而不是 thresholds

另外,请注意,如果您更新到 > 1.2.0 的版本。 threshold 是更新以获取两个对象 globaleach,如下所述:https://github.com/mattlewis92/karma-coverage-istanbul-reporter/blob/master/README.md