【问题标题】:Karma runner with Coverage - preprocessor not working on Javascript ES6 code带有 Coverage 的 Karma 跑步者 - 预处理器不适用于 Javascript ES6 代码
【发布时间】:2019-12-20 02:25:41
【问题描述】:

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

但是,现在我决定跟踪代码覆盖率。为了测量它,我需要在我的源代码上运行预处理器。这就是我偶然发现一个问题的地方 - 我目前正在努力使其工作并且两者都有一些问题

  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文件(尽管地址和覆盖预处理器的情况一样)并返回这个错误。

 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 包每个月都会不断出现,所以我真的不确定哪个最好用。

非常感谢

【问题讨论】:

    标签: ecmascript-6 sapui5 karma-runner code-coverage karma-babel-preprocessor


    【解决方案1】:

    我们遇到了同样的问题,我们设法在 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 代码并打印覆盖率。

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

    【讨论】:

    • 您好,非常感谢您的详细解答。我们还不能让它运行,因为我们一开始没有构建 ui5,但它给了我们一些想法。
    • 好的,更新 - 最后,我们添加了 ui-building-tool 步骤并使用了您的源代码。一切正常,源代码不仅被正确转译,而且被缩小。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2017-01-25
    • 2016-09-09
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    相关资源
    最近更新 更多