2
votes

After updating to angular 7 from angular 6 with minimal code changes in our code repository, karma uni test runs became very slow, and when running with the watch parameter set to true, it fails to reload/re-bundle the tests immediately after saving a file, where mostly it takes 4 minutes after saving a file to re-trigger the test runner, or in some cases it times-out. A single ng test karma run with angular 7 usually takes about 3 minutes as it did in angular 6. The 4 minutes slow time in angular 7 is persisting even when running a single spec file, which used to take mere seconds to run and rebuild before upgrading to angular 7.

Package.json file content:

{
  "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"
  }
}

And my karma config file content:

// 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'
        ]
      }
    }
  });
};

finally, my test.ts file content:

// 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();
1
There is no example. The same setup and configuration that was running on angular 6, simple stopped running as it used to when we use the --watch flag and run karma! The tests take about 4 minutes on every rebuild/re-bundle on saving a file, which used to required seconds. I'm going to add the config file contents for reference. - Samer
I am facing similar issue. Do you have a fix now? - Jagpreet Singh
I would suggest you to exclude testing options one by one to find a bottleneck: coverage, reporters, sourcemaps... This could allow you to have a repro within single Angular 7 project configuration - dhilt
Similar issue on Angular 6, see: stackoverflow.com/a/53479499/984471 - Manohar Reddy Poreddy

1 Answers

0
votes

In our case, we needed to use an Angular high memory package to avoid timeouts caused by the large list of tests, which Angular CLI is not designed to handle.