如何用sailsjs中的毯子和摩卡测试覆盖率

时间:2014-04-12 08:50:45

标签: mocha sails.js blanket.js

我有一个带有test/文件夹的Sails项目,其中包含我的所有mocha测试,并希望使用以下命令创建测试覆盖率报告:

mocha --require blanket --reporter html-cov > coverage.html

package.json内的总帐配置如下:

"blanket": {
  "pattern": ["lib", "api", "config"],
  "data-cover-never": "node_modules",
  "data-cover-reporter-options": {
    "shortnames": true
  }
}

我同时包含了Sails文件夹api/config/,因为它们可能包含可测试代码和包含我应用程序逻辑的大部分文件夹lib/

遗憾的是,blanket覆盖率模块仅涵盖直接包含在我的测试文件中的文件。由于Sails会动态加载api/config/中的大多数文件,因此它们不会显示在我的报道中。

关于如何将Sails框架与毯子集成的任何想法?

1 个答案:

答案 0 :(得分:1)

我对Sails不感兴趣,但我使用Blanket.js遇到了同样的问题,并在Blanket.js错误跟踪器上发布了一个解决方案,这里是:

https://github.com/alex-seville/blanket/issues/361#issuecomment-34002054

我建议的解决方法非常像黑客。我最终放弃了Blanket,转而支持伊斯坦布尔:https://github.com/gotwarlost/istanbul

伊斯坦布尔为您提供更多指标(声明,行,功能和分支覆盖),并输出一组优秀的.html文件,以便您分析如何改进代码。

鉴于目前有79个以上未解决的问题,

Blanket.js似乎没有得到很好的维护。

如果您确实想坚持使用blanket.js,您可以按照我在Blanket.js错误跟踪器上发布的建议,并尝试通过递归循环遍历所有相关代码目录来包含测试运行中的所有文件。我以前用来做的代码如下(我肯定会重构这个,但它显示了意图):

'use strict';

/**
 * This file is loaded by blanket.js automatically before it instruments code to generate a code coverage report.
 */

var fs = require('fs');
var log = require('winston');
var packageJson = require('./package.json');

// For some reason the blanket config in package.json does not work automatically, set the settings manually instead
require('blanket')({
    // Only files that match this pattern will be instrumented
    pattern: packageJson.config.blanket.pattern
});

/**
 * Walks through a directory structure recursively and executes a specified action on each file.
 * @param dir {(string|string[])} The directory path or paths.
 * @param action {function} The function that will be executed on any files found.
 *      The function expects two parameters, the first is an error object, the second the file path.
 */
function walkDir(dir, action) {

    // Assert that action is a function
    if (typeof action !== "function") {
        action = function (error, file) {
        };
    }

    if (Array.isArray(dir)) {
        // If dir is an array loop through all elements
        for (var i = 0; i < dir.length; i++) {
            walkDir(dir[i], action);
        }
    } else {
        // Make sure dir is relative to the current directory
        if (dir.charAt(0) !== '.') {
            dir = '.' + dir;
        }

        // Read the directory
        fs.readdir(dir, function (err, list) {

            // Return the error if something went wrong
            if (err) return action(err);

            // For every file in the list, check if it is a directory or file.
            // When it is a directory, recursively loop through that directory as well.
            // When it is a file, perform action on file.
            list.forEach(function (file) {
                var path = dir + "/" + file;
                fs.stat(path, function (err, stat) {
                    if (stat && stat.isDirectory()) {
                        walkDir(path, action);
                    } else {
                        action(null, path);
                    }
                });
            });
        });
    }
};

// Loop through all paths in the blanket pattern
walkDir(packageJson.config.blanket.pattern, function (err, path) {
    if (err) {
        log.error(err);
        return;
    }
    log.error('Including ' + path + ' for blanket.js code coverage');
    require(path);
});

我的建议是将Blanket.js放到其他地方。