在 Angular 7 更新后,karma 无法 运行 带有 watch flag

karma fails to run with watch flag after Angular 7 update

从 angular 6 更新到 angular 7 后,我们的代码存储库中的代码更改很少,karma uni test 运行s 变得非常慢,当 运行 watch 参数设置为 true,它无法在保存文件后立即 reload/re-bundle 测试,其中大多数情况下保存文件后需要 4 分钟才能重新触发测试 运行ner,或者在某些情况下它超时了。 ng test karma 运行 with angular 7 通常需要大约 3 分钟,就像在 angular 6 中那样。angular 7 中的 4 分钟慢时间持续存在即使 运行 只需要几秒钟就可以 运行 并在升级到 angular 7.

之前重建单个规范文件

Package.json文件内容:

{
  "name": "my proj",
  "description": "asdfa",
  "version": "0.0.0-development",
  "license": "UNLICENSED",
  "scripts": {
    "ng": "ng",
    "start": "ng serve --hmr",
    "build": "ng build",
    "build-ci": "ng build --prod",
    "test": "ng test --code-coverage",
    "test-ci": "ng test --watch=false --browsers ChromeHeadlessNoSandbox --code-coverage",
    "lint": "tslint --project .",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependenciesComments": {
    "angular-split-ng6": "This is a fork of the main (abandoned) angular-split library. The fork includes rxjs 6 upgrade."
  },
  "dependencies": {
    "@angular/animations": "^7.0.0",
    "@angular/cdk": "^7.0.0",
    "@angular/common": "^7.0.0",
    "@angular/compiler": "^7.0.0",
    "@angular/core": "^7.0.0",
    "@angular/forms": "^7.0.0",
    "@angular/http": "^7.0.0",
    "@angular/material": "^7.0.0",
    "@angular/material-moment-adapter": "^7.0.0",
    "@angular/platform-browser": "^7.0.0",
    "@angular/platform-browser-dynamic": "^7.0.0",
    "@angular/router": "^7.0.0",
    "@angularclass/hmr": "^2.1.3",
    "@ngrx/core": "^1.2.0",
    "@ngrx/effects": "^6.0.1",
    "@ngrx/router-store": "^6.0.1",
    "@ngrx/store": "^6.0.1",
    "@ngrx/store-devtools": "^6.0.1",
    "@ngx-translate/core": "^10.0.1",
    "@ngx-translate/http-loader": "^3.0.1",
    "@nicky-lenaers/ngx-scroll-to": "^1.0.0",
    "adal-angular": "^1.0.16",
    "ag-grid": "^18.1.0",
    "ag-grid-angular": "^18.1.0",
    "ag-grid-enterprise": "^18.1.0",
    "angular-split-ng6": "^1.0.0-rc.5",
    "angular2-jwt": "^0.2.3",
    "angular2-prettyjson": "^2.0.6",
    "applicationinsights-js": "^1.0.20",
    "core-js": "^2.5.3",
    "d3": "5.7.0",
    "deepmerge": "^1.5.1",
    "expose-loader": "^0.7.4",
    "fast-json-patch": "^2.0.6",
    "hammerjs": "^2.0.8",
    "juice": "^4.3.2",
    "moment": "^2.20.1",
    "ng2-dragula": "^1.5.0",
    "ngrx-store-freeze": "^0.2.0",
    "ngx-order-pipe": "^2.0.1",
    "ngx-perfect-scrollbar": "^6.0.0",
    "ngx-quill": "^3.1.0",
    "ngx-scrollspy": "^1.2.1",
    "particle-ui": "../particle-ui/src/lib",
    "quill": "^1.3.6",
    "quill-delta": "^3.6.3",
    "rxjs": "^6.3.3",
    "sax": "^1.2.4",
    "stream": "0.0.2",
    "timers": "^0.1.1",
    "web-animations-js": "^2.3.1",
    "xml2js": "^0.4.19",
    "xmlbuilder": "^10.0.0",
    "zone.js": "0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.10.3",
    "@angular/cli": "^7.0.1",
    "@angular/compiler-cli": "^7.0.0",
    "@angular/language-service": "^7.0.0",
    "@types/adal": "^1.0.27",
    "@types/applicationinsights-js": "^1.0.5",
    "@types/d3": "5.0.0",
    "@types/deepmerge": "^1.3.3",
    "@types/jasmine": "^2.8.6",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^8.5.2",
    "@types/xml2js": "^0.4.3",
    "angular2-template-loader": "^0.6.2",
    "awesome-typescript-loader": "^3.5.0",
    "codelyzer": "^4.3.0",
    "jasmine-core": "^2.99.1",
    "jasmine-marbles": "^0.3.1",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "~3.1.1",
    "karma-chrome-launcher": "^2.2.0",
    "karma-cli": "~1.0.1",
    "karma-coverage": "^1.1.1",
    "karma-coverage-istanbul-reporter": "^1.4.1",
    "karma-jasmine": "^1.1.1",
    "karma-scss-preprocessor": "^3.0.0",
    "karma-spec-reporter": "^0.0.32",
    "karma-spec-reporter-2": "^0.2.0",
    "karma-trx-reporter": "^0.2.9",
    "protractor": "^5.2.2",
    "rxjs-tslint": "^0.1.5",
    "ts-node": "^3.3.0",
    "tslint": "^5.11.0",
    "tslint-defocus": "^2.0.5",
    "tslint-language-service": "^0.9.9",
    "typescript": "3.1.x",
    "wallaby-webpack": "^3.9.5"
  }
}

我的业力配置文件内容:

// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-coverage'),
      require('karma-coverage-istanbul-reporter'),
      require('karma-spec-reporter'),
      require('karma-trx-reporter'),
      require('karma-scss-preprocessor'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      captureConsole: true,
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    files: [
      { pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', includes: true }
    ],
    preprocessors: {
    },
    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, 'coverage'), reports: ['lcovonly', 'cobertura', 'html', 'text-summary', 'text'],
      fixWebpackSourcePaths: true,
      'report-config': {
        cobertura: {
          file: 'cobertura-coverage.xml'
        }
      }
    },
    angularCli: {
      environment: 'dev',
      codeCoverage: true
    },
    reporters: ['spec', 'trx', 'coverage-istanbul'],
    specReporter: {
      lateReport: true,
      showSpecTiming: true, // print the time elapsed for each spec
      slowTestTime: 40, // karma-spec-reporter-2
      fastTestTime: 20 // karma-spec-reporter-2
    },
    trxReporter: {
      outputFile: 'coverage/test-results.trx',
      shortTestName: false
    },
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    browsers: ['ChromeHeadlessNoSandbox'],
    browserNoActivityTimeout: 60000, // default is 10000
    browserDisconnectTimeout: 10000, // default is 2000
    captureTimeout: 60000, // default is 60000
    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: [
          '--no-sandbox',
          '--no-proxy-server',
          '--disable-gpu' // https://bugs.chromium.org/p/chromium/issues/detail?id=737678
        ]
      },
      ChromeDebug: {
        base: 'Chrome',
        flags: [
          '--remote-debugging-port=9222'
        ]
      }
    }
  });
};

最后,我的test.ts文件内容:

// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed } from '@angular/core/testing';
import {
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
// tslint:disable-next-line:no-any
declare const __karma__: any;
// tslint:disable-next-line:no-any
declare const require: any;

import { LicenseManager } from 'ag-grid-enterprise/main';
import { environment } from './environments/environment';
LicenseManager.setLicenseKey(environment.licenses['ag-grid']);

// Prevent Karma from running prematurely.
__karma__.loaded = function () { };

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();

在我们的例子中,我们需要使用 Angular 高内存包来避免由大量测试导致的超时,Angular CLI 并非旨在处理这种情况。