具有 Coverage 的 Karma runner - 预处理器无法处理 Javascript ES6 代码

Karma runner with Coverage - preprocessor not working on Javascript ES6 code

我最近才开始在我们的 UI5 应用程序中使用 Karma 运行ner。写了一些单元测试,运行 它们...到目前为止一切正常。

但是,现在我决定跟踪代码覆盖率。为了测量它,我需要对我的源代码进行 运行 预处理器。这就是我偶然发现问题的地方——我目前正在努力让它发挥作用,但都遇到了一些问题

  1. npm package karma-coverage 作为预处理器 - 安装后,我在 karma.conf.js 中这样设置
preprocessors: {   
    "webapp/helpers/**/*.js": ['coverage'],  
    "webapp/controller/**/*.js": ['coverage'], 
},

这在 helpers 文件夹中工作正常,因为它只包含一个简单的 javascript 文件。但是,当它尝试处理包含带有某些 ES6 代码的文件的 controller 文件夹时,每个文件都会失败并出现诸如

之类的错误
Unexpected token function
Unexpected token ...
  1. 作为第二种选择,我尝试使用 karma-babel-preprocessor,它应该也能够处理 ES6 代码。这就是我的 karma.conf.js 文件的样子

    预处理器:{ "webapp/helpers//.js": ['babel'], "webapp/controller//.js": ['babel'], },

    babelPreprocessor: {
      options: {
        presets: ['@babel/preset-env'],
        sourceMap: 'inline'
      } ,
      filename: function (file) {
        return file.originalPath.replace(/\.js$/, '.es5.js');
      },
      sourceFileName: function (file) {
        return file.originalPath;
      } 
    },
    

然而,这个甚至无法找到js文件(即使地址与覆盖预处理器的情况相同)并且returns这个错误。

 Error: failed to load 'sbn/portal/helpers/formatter.js' from .webapp/helpers/formatter.js: 404 - Not Found
  at https://openui5.hana.ondemand.com/resources/sap-ui-core.js:86:37

有人知道我如何在使用这些软件包或任何其他软件包时获取覆盖率数据吗?网上有很多相互矛盾的信息,其中大部分已经有好几年了,而各种与 karma 相关的 npm 包每个月都会不断弹出,所以我真的不确定哪个最好用。

非常感谢

我们遇到了同样的问题,我们设法在 ui5-building-tool 步骤中集成 babel 来修复它。

这就是我们的 package.json 的样子:

 {
        "devDependencies": {
            "babel-core": "6.26.3",
            "babel-plugin-fast-async": "6.1.2",
            "babel-preset-env": "1.7.0",
            "karma": "^4.0.1",
            "karma-chrome-launcher": "^2.2.0",
            "karma-coverage": "^1.1.2",
            "karma-ui5": "^1.0.0",
            "karma-junit-reporter": "1.2.0",
            "rimraf": "^2.6.2",
            "start-server-and-test": "^1.4.1",
            "@ui5/cli": "^1.5.5",
            "@ui5/logger": "^1.0.0",
        }
        "scripts": {
            "start": "ui5 serve -o index.html",
            "lint": "eslint webapp",
            "test": "karma start",
            "build": "npm run test && rimraf dist && ui5 build --a --include-task=generateManifestBundle"
      }
    }

这就是 ui5.yaml 的样子

specVersion: '1.0'
metadata:
  name: app-name
type: application
builder:
    customTasks:
    - name: transpile
      afterTask: replaceVersion
---
specVersion: "1.0"
kind: extension
type: task
metadata:
    name: transpile
task:
    path: lib/transpile.js

这是 transpile.js 的样子:

请注意,此文件应放在 root-dir/lib 文件夹中。 root-dir 是 ui5.yaml 所在的文件夹。

const path = require("path");
const babel = require("babel-core");
const log = require("@ui5/logger").getLogger("builder:customtask:transpile");

/**
 * Task to transpiles ES6 code into ES5 code.
 *
 * @param {Object} parameters Parameters
 * @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
 * @param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
 * @param {Object} parameters.options Options
 * @param {string} parameters.options.projectName Project name
 * @param {string} [parameters.options.configuration] Task configuration if given in ui5.yaml
 * @returns {Promise<undefined>} Promise resolving with undefined once data has been written
 */
module.exports = function ({
    workspace,
    dependencies,
    options
}) {
    return workspace.byGlob("/**/*.js").then((resources) => {
        return Promise.all(resources.map((resource) => {
            return resource.getString().then((value) => {
                log.info("Transpiling file " + resource.getPath());
                return babel.transform(value, {
                    sourceMap: false,
                    presets: [
                        [
                            "env",
                            {
                                exclude: ["babel-plugin-transform-async-to-generator", "babel-plugin-transform-regenerator"]
                            }
                        ]
                    ],
                    plugins: [
                        [
                            "fast-async",
                            {
                                spec: true,
                                compiler: {
                                    "promises": true,
                                    "generators": false
                                }
                            }
                        ]
                    ]
                });
            }).then((result) => {
                resource.setString(result.code);
                workspace.write(resource);
            });
        }));
    });
};

最后是 karma.conf.js 设置:

module.exports = function (config) {
    var ui5ResourcePath = "https:" + "//sapui5.hana.ondemand.com/resources/";
    config.set({

        // the time that karma waits for a response form the browser before closing it
        browserNoActivityTimeout: 100000,

        frameworks: ["ui5"],

        // list of files / patterns to exclude
        exclude: [],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
           "root_to_to_files/**/*.js": ["coverage"],
        },

        // test results reporter to use
        // possible values: "dots", "progress"
        // available reporters: https://npmjs.org/browse/keyword/karma-reportery
        reporters: ["progress", "coverage"],

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

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

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: false,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ["Chrome"],

        // Continuous Integration modey
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: Infinity,

        // generates the coverage report
        coverageReporter: {
            type: "lcov", // the type of the coverage report 
            dir: "reports", // the path to the output directory where the coverage report is saved
            subdir: "./coverage" // the name of the subdirectory in which the coverage report is saved
        },

        browserConsoleLogOptions: {
            level: "error"
        }


    });
};

在我们的项目中,此设置适用于 ES6 代码并打印覆盖率。

希望这对你有所帮助。请给我反馈这是如何工作的。