Typescript 代码在调试单元测试时启用了覆盖率

Posted

技术标签:

【中文标题】Typescript 代码在调试单元测试时启用了覆盖率【英文标题】:Typescript code has coverage enabled when debugging unit tests 【发布时间】:2020-02-19 10:36:24 【问题描述】:

我有一个混合使用 TypeScript 和 javascript 的混合 Angular 应用程序(1.7.5 和 8.2.10 之间的混合)。

为了运行单元测试,我有两个单独的 npm 脚本,一个用于 ngX 测试,一个用于 ng1 测试。

我的问题是,当我运行我的 ng1 测试进行调试时,打字稿代码总是启用代码覆盖率,这意味着它被缩小并且有额外的代码行来计算我遇到的行/分支/语句/函数。这显然使调试成为主要的烦恼。这是我运行测试的 npm 脚本

 "test:ng1": "karma start ./src/karma.ng1.conf.js",

下面是我运行的配置示例,删除了所有覆盖插件,以防止覆盖代码应用于我的打字稿:

module.exports = function(config) 

  var reporters = ['mocha', 'kjhtml'];
  // Only implement coverage if the coverage argument was set
  if(config.coverage)
    reporters.push('coverage-istanbul');
    console.log('Coverage enabled');
  
  else
    console.log('Coverage not enabled');
  

  config.set(
    // base path, that will be used to resolve files and exclude
    basePath: '../',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['jasmine', 'karma-typescript'],

    preprocessors: 
      'src/app/**/*.ts': ['karma-typescript'],
      'src/test/spec/**/*.ts': ['karma-typescript'],
      // 'src/app/modules/ng1/**/*.js': ['karma-coverage-istanbul-instrumenter'],
      // 'src/app/modules/ng1/**/*.ts': ['karma-typescript', 'karma-coverage-istanbul-instrumenter'],
      '**/*.html': ['ng-html2js']
    ,
    mime: 
      'text/x-typescript': ['ts','tsx']
    ,

    // list of files / patterns to load in the browser
    files: [
      'node_modules/babel-polyfill/browser.js',
      'node_modules/jquery/dist/jquery.js',
      'node_modules/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'node_modules/angular-animate/angular-animate.js',
      'node_modules/angular-cookies/angular-cookies.js',
      'node_modules/angular-resource/angular-resource.js',
      'node_modules/angular-sanitize/angular-sanitize.js',
      'node_modules/@uirouter/angularjs/release/angular-ui-router.js',
      'node_modules/ui-bootstrap4/dist/ui-bootstrap-tpls.js',
      'node_modules/lodash/lodash.js',
      'node_modules/angular-growl-v2/build/angular-growl.js',
      'node_modules/angular-jquery-timepicker/src/timepickerdirective.js',
      'node_modules/timepicker/jquery.timepicker.js',
      'node_modules/angularjs-scroll-glue/src/scrollglue.js',
      'node_modules/angular-translate/dist/angular-translate.js',
      'node_modules/moment/moment.js',
      'node_modules/ngstorage/ngStorage.js',
      'node_modules/jasmine-promise-matchers/dist/jasmine-promise-    matchers.js',
      'node_modules/angular-ui-grid/ui-grid.js',
      'src/app/*.ts',
      'src/app/modules/**/*.js',
      'src/app/modules/**/*.ts',
      'src/app/partials/**/*.html',
      'src/test/spec/ipsmicaTestFixtures.js',
      'src/test/spec/**/*.spec.js',
      'src/test/spec/**/*.spec.ts'
    ],

    // list of files / patterns to exclude
    exclude: [
      'src/app/modules/ngX/**/*.spec.ts'
    ],

    ngHtml2JsPreprocessor: 
      cacheIdFromPath: function(filepath) 
        return filepath.replace('src/app/partials/', '');
      ,

      moduleName: 'ipsmica.templates'
    ,

    // web server port defaults to 9876
    browsers: [
      'ChromeHeadless'
    ],
    browserNoActivityTimeout: 60000,

    // Code coverage report
    reporters: reporters,

    mochaReporter: 
      ignoreSkipped: true
    ,

    // coverageIstanbulReporter: 
    //   reports: ['text-summary', 'html'],
    //   fixWebpackSourcePaths: true,
    //   dir: 'target/coverage/ng1',
    //   subdir: '.'
    // ,

    // Which plugins to enable
    plugins: [
      'karma-chrome-launcher',
      'karma-jasmine',
      // 'karma-coverage-istanbul-reporter',
      'karma-jasmine-html-reporter',
      // 'karma-coverage-istanbul-instrumenter',
      'karma-mocha-reporter',
      'karma-ng-html2js-preprocessor',
      'karma-typescript'
    ],
    tsconfig: 'tsconfig.spec.json',
    colors: true,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO ||     LOG_DEBUG
    logLevel: config.LOG_INFO
  );
;

使用此配置,打字稿代码在调试时仍然嵌入了覆盖代码。 如何禁用此功能?

【问题讨论】:

【参考方案1】:

对于遇到此问题的任何人来说,问题在于 karma-typescript 自动启用代码覆盖,所以我只需要添加一个设置来禁用它并启用源映射

在我的业力配置中

karmaTypescriptConfig = 
  bundleOptions:
    sourceMap: true
  ,
  coverageOptions:
    instrumentation : false
  
;

【讨论】:

以上是关于Typescript 代码在调试单元测试时启用了覆盖率的主要内容,如果未能解决你的问题,请参考以下文章

Typescript/React 单元测试库,能够单步调试导入的函数

在 vs 代码中调试用 typescript 节点编写的 jasmine 测试

如何使用 Visual Studio Code 中的 Mocha 调试 Typescript 编写的单元测试

启用 proguard 的 Android 单元测试

TypeScript 中的单元测试 [关闭]

Angular2(TypeScript)中的单元测试/模拟窗口属性