Не удается найти исходные карты для Karma + Jasmine + TypeScript + Webpack

Я пытаюсь протестировать (с охватом) свое приложение TypeScript, используя Karma, Jasmine и Webpack. Со следующим: я могу успешно запускать тесты, но не могу правильно создать покрытие. Я использую karma-remap-coverage (https://github.com/sshev/karma-remap-coverage) и кажется достаточно простым.

Выглядит как будто происходит что-то интересное (и я получаю какой-то отчет о покрытии), но с несколькими настройками здесь и там цифры резко меняются, и я никогда не могу загрузить исходные карты.

Вот базовая настройка:

У меня есть каталог src, содержащий 10 файлов .ts. На данный момент только у одного есть соответствующий файл .spec.

Файл spec довольно прост, и его было достаточно, чтобы доказать, что я могу запускать тесты:

import ComponentToTest from './componentToTest';

describe('ComponentToTest', () => {

  it('should run a test', () => {
      expect(1+1).toBe(2);
  });

  it('should be able to invoke the a method', () => {
      spyOn(ComponentToTest, 'foo').and.callThrough();
      ComponentToTest.foo('testing foo');
      expect(ComponentToTest.foo).toHaveBeenCalled();
  });

});

Это прекрасно работает в паре с моим файлом tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "noImplicitAny": false,
    "sourceMap": true,
    "lib": ["es6", "dom"],
    "experimentalDecorators": true
  },
  "exclude": [
    "node_modules"
  ]
}

и karma.conf.js файл:

module.exports = config => config.set({

    frameworks: ['jasmine'],

    mime: { 'text/x-typescript': ['ts','tsx'] },

    // if I make this a generic './src/**/*.ts' it seems to freeze up
    // without throwing any errors or running any tests, but that seems
    // like a separate issue...
    files: [
        './src/lib/componentToTest.ts',
        './src/lib/componentToTest.spec.ts'
    ],

    preprocessors: {
        './src/**/*.spec.ts': ['webpack'],
        './src/**/*.ts': ['webpack', 'sourcemap', 'coverage']
    },

    webpack: {
        devtool: "source-map",
        module: {
            rules: [
                {
                    test: /\.ts?$/,
                    loader: 'ts-loader',
                    exclude: /node_modules/
                }
            ]
        },
        resolve: {
            extensions: [".ts", ".js"]
        }
    },

    webpackMiddleware: {
        quiet: true,
        stats: {
            colors: true
        }
    },

    // add both "karma-coverage" and "karma-remap-coverage" reporters
    reporters: ['progress', 'coverage', 'remap-coverage'],

    // save interim raw coverage report in memory
    coverageReporter: {
        type: 'in-memory'
    },

    // define where to save final remaped coverage reports
    remapCoverageReporter: {
        'text-summary': null,
        html: './coverage/html',
        cobertura: './coverage/cobertura.xml'
    },

    colors: true,

    // 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

});

И, наконец, запускаю тесты простой задачей Gulp:

gulp.task('test', function (done) {
  new Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true
  }, (exitCode) => {
     done();
     process.exit(exitCode);
  }).start();
});

При запуске я получаю результат, который кажется (в основном) многообещающим:

Chrome 58.0.3029 (Mac OS X 10.12.3): Executed 1 of 2 SUCCESS (0 secs / 0.002 secs)
Chrome 58.0.3029 (Mac OS X 10.12.3): Executed 2 of 2 SUCCESS (0.026 secs / 0.004 secs)
[Error: Could not find source map for: "app/src/lib/componentToTest.ts"]
[Error: Could not find source map for: "app/src/lib/componentToTest.spec.ts"]

========================= Coverage summary =========================
Statements   : 43.69% ( 322/737 )
Branches     : 15.7% ( 38/242 )
Functions    : 35.47% ( 61/172 )
Lines        : 44.91% ( 322/717 )
====================================================================

Значит, что-то происходит! Что заставляет меня чувствовать, что я рядом. Когда я просматриваю свой отчет о покрытии в браузере, я вижу в списке как файл .spec.ts, так и файл .ts (который снова становится ближе), но я не совсем там по нескольким причинам:

  1. Файл .spec.ts включается в отчет о покрытии. Поскольку это тестовый файл, я не хочу его включать.
  2. Исходные карты не генерируются должным образом — это видно из ошибок в консоли, а также из невозможности перейти к отчету о покрытии конкретного файла.

Я чувствую, что я чертовски близок. Есть ли что-то простое, что мне не хватает или предложения?

Обновление:

Я понял, что использую более старую версию Node, и подумал, что это может вызывать некоторые проблемы. Я обновился до 6.11.0, и хотя это ничего не решило, он дал немного больше контекста:

Об ошибках сообщает remap-istanbul (в этом нет ничего удивительного):

CoverageTransformer.addFileCoverage (/app/node_modules/remap-istanbul/lib/CoverageTransformer.js:148:17)

Я использую [email protected], который использует [email protected] — кажется, что в прошлом были проблемы с remap-istanbul, но не в той версии, которую я использую.

Также использую Webpack 2.6.1 и TypeScript 2.3.2


person amlyhamm    schedule 23.06.2017    source источник


Ответы (1)


Что ж, после нескольких дней проб и ошибок я наконец нашел работающее решение. Я не уверен конкретно, что вызвало проблему в моем первом посте, но вот где я оказался. Это может быть полезно для тех, кто ищет действительно простую настройку TypeScript, Karma, Jasmine, Webpack (с покрытием).

  • Моя файловая структура и файл spec остались прежними.
  • Мой tsconfig.json обновлен до:

    {
      "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "inlineSourceMap": true, // this line
        "sourceMap": false, // and this one
        "experimentalDecorators": true,
        "lib": ["es6", "dom"]
      },
      "exclude": [
          "node_modules"
      ]
    }
    
  • Я переключился на использование awesome-typescript-loader вместо ts-loader.

  • И, наконец, мой файл karma.conf.js теперь выглядит так:

    module.exports = config => config.set({
    
        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',
    
        frameworks: ['jasmine'],
    
        mime: { 'text/x-typescript': ['ts','tsx'] },
    
        files: [
            'node_modules/angular/angular.min.js',
            './src/**/*.ts'
        ],
    
        preprocessors: {
            './src/**/*.ts': ['webpack']
        },
    
        webpack: {
    
            devtool: 'inline-source-map',
            module: {
                rules: [
                    {
                        enforce: 'pre',
                        test: /\.js$/,
                        loader: 'source-map-loader',
                        exclude: [
                            'node_modules',
                            /\.spec\.ts$/
                        ]
                    },
                    {
                        test: /\.ts?$/,
                        use: [
                            {
                                loader: 'awesome-typescript-loader',
                                query: {
                                    /**
                                     * Use inline sourcemaps for "karma-remap-coverage" reporter
                                     */
                                    sourceMap: false,
                                    inlineSourceMap: true,
                                    compilerOptions: {
                                        removeComments: true
                                    }
                                },
                            }
                        ]
                    },
                    {
                        enforce: 'post',
                        test: /\.(js|ts)$/,
                        loader: 'istanbul-instrumenter-loader',
                        exclude: [
                            /node_modules/,
                            /\.spec\.ts$/
                        ]
                    },
                    { test: /\.html$/, loader: 'html-loader' }
                ]
            },
            resolve: {
                extensions: [".ts", ".js", ".html"]
            },
            externals: {
                angular: "angular"
            }
        },
    
        webpackMiddleware: {
            quiet: true,
            stats: {
                colors: true
            }
        },
    
        // add both "karma-coverage" and "karma-remap-coverage" reporters
        reporters: ['progress', 'coverage', 'remap-coverage'],
    
        // save interim raw coverage report in memory
        coverageReporter: {
            type: 'in-memory'
        },
    
        // define where to save final remaped coverage reports
        remapCoverageReporter: {
            'text-summary': null,
            html: './coverage/html',
            cobertura: './coverage/cobertura.xml'
        },
    
        colors: true,
    
        // 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
    
    });
    

Окончательные версии пакетов включают:

  • node 4.2.6 (Мне также удалось заставить это работать с более новой версией узла, но я должен быть здесь по другим причинам)
  • удивительный машинописный загрузчик 3.1.2
  • Стамбульский инструментарий-загрузчик 2.0.0
  • жасмин ядро ​​2.5.2
  • карма 1.6.0
  • карма-хром-лаунчер 2.0.0
  • карма-покрытие 1.1.1
  • карма-жасмин 1.1.0
  • карма-ремап-покрытие 0.1.4
  • карма-вебпак 2.0.3
  • машинопись 2.3.2
  • веб-пакет 2.6.1

Теперь мои тесты работают, в консоли нет ошибок, и у меня есть отчет о покрытии исходных файлов TypeScript!

Большое спасибо людям, которые собрали это вместе (в итоге это помогло мне в окончательном решении): https://github.com/AngularClass/angular-starter/tree/master/config

person amlyhamm    schedule 27.06.2017
comment
У меня также в какой-то момент работал AngularStarter. У меня есть покрытие кода и все, кроме того факта, что при отладке в Chrome я вижу, что мой машинописный текст скомпилирован в ES5/ES6, а не в исходный. В чем может быть проблема? - person norekhov; 15.06.2018