【问题标题】:Logging with grunt and qunit使用 grunt 和 qunit 进行日志记录
【发布时间】:2014-02-16 13:27:14
【问题描述】:

我正在使用 grunt/qunit 运行 javascript 单元测试。有时测试会因为源文件中的语法错误而失败(如果测试文件中引入了语法错误,则可以很好地处理文件信息)。发生这种情况时,grunt 只会打印行号,而不是问题所在的文件。

Running "qunit:all" (qunit) task
Warning: Line 99: Unexpected identifier Use --force to continue.

Aborted due to warnings.

这没有多大帮助,因为我有 100 个 js 文件。我调查过:

https://github.com/gruntjs/grunt-contrib-qunit

并尝试将以下内容添加到我的 Gruntfile.js (grunt.event.on):

module.exports = function(grunt) {
    "use:strict";
    var reportDir = "output/reports/"+(new Date()).getTime().toString();
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        qunit: {
            options: {
                '--web-security': 'no',
                coverage: {
                    src: ['../src/**/*.js'],
                    instrumentedFiles: 'output/instrument/',
                    htmlReport: 'output/coverage',
                    coberturaReport: 'output/',
                    linesTresholdPct: 85
                }
            },
            all: ["testsSuites.html"]
        }
    });


    // Has no effect
    grunt.event.on('qunit.error.onError', function (msg, stack) {
        grunt.util._.each(stack, function (entry) {
            grunt.log.writeln(entry.file + ':' + entry.line);
        });
        grunt.warn(msg);
    });     

    grunt.loadNpmTasks('grunt-contrib-qunit');
    grunt.loadNpmTasks('grunt-qunit-istanbul');
    grunt.registerTask('test', ['qunit']);

testSuites.html 包含的位置:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="qunit/qunit.css">
    <script src="qunit/qunit.js"></script>
    <script src="sinonjs/sinon-1.7.3.js"></script>
    <script src="sinonjs/sinon-qunit-1.0.0.js"></script>

    <!-- Sources -->
    <script src="../src/sample.js"></script>

    <!-- Test-->
    <script src="test/sample-test.js"></script>

  </head>
  <body>
    <div id="qunit"></div>
    <div id="qunit-fixture"></div>
    <script>
    </script>
  </body>
</html>

但是问题所在的源文件还是没有打印出来。是否无法验证源代码/显示行号/文件,例如语法错误所在的位置?

我也试过跑步:

grunt test --debug 9

它会打印一些调试信息,但不会打印有关 javascript 源中的语法错误的任何信息。

我尝试安装 JSHint 并在我所有的 javascript 源文件中调用它:

for i in $(find ../src -iname "*.js"); do jshint $i; done

现在我遇到了很多错误,但 Grunt 仍然很高兴。如果我引入一个简单的语法错误,例如:

(function(){
   var sampleVar 32;

}

在 Grunt 中引发错误:

Running "qunit:all" (qunit) task
Warning: Line 2: Unexpected number Use --force to continue.

Aborted due to warnings.

它只是在 JSHint 生成的错误流中消失了。如何从实际上会使 Grunt 失败的严重错误中过滤 JSHint“警告”?

还是应该为更详细的输出配置 qunit?

【问题讨论】:

  • 你是否对--debug 9标志感到不满?
  • 您可以在源文件上运行 jshint。它会修复你的语法错误。
  • 修复?我猜你的意思是通知? jshint.com/docs 似乎只适用于单个文件。但也许 jslint 支持在例如 js 文件 github.com/reid/node-jslint 的文件夹上运行语法检查
  • 您是否有一个展示这些问题的示例项目可以尝试?
  • 在运行测试时如何包含源文件?作为all_tests.html 中的&lt;script&gt; 标签,还是其他地方?

标签: javascript unit-testing gruntjs


【解决方案1】:

grunt-contrib-qunit 将在遇到语法错误时显示文件名。拿这个简化版的Gruntfile.js

module.exports = function(grunt) {
    "use:strict";
    grunt.initConfig({
        qunit: {
            options: { '--web-security': 'no' },
            all: ["testsSuites.html"]
        }
    });

    grunt.loadNpmTasks('grunt-contrib-qunit');
};

运行它会给出您正在寻找的错误:

$ grunt qunit
Running "qunit:all" (qunit) task
Testing testsSuites.html F.
>> global failure
>> Message: SyntaxError: Parse error
>> file:///tmp/src/sample.js:2

Warning: 1/2 assertions failed (17ms) Use --force to continue.

Aborted due to warnings.

您遇到的问题看起来是grunt-qunit-istanbul 中的错误(?)。您收到的警告:

Warning: Line 99: Unexpected identifier Use --force to continue.

Grunt 正在处理未捕获的异常。 grunt-qunit-istanbul 任务引发了异常。您可以通过修改原始Gruntfile.js 中的这一行来证明这一点:

src: ['../src/**/*.js'],

到:

src: ['../src/**/*.js.nomatch'],

这将阻止grunt-qunit-istanbul 在 Qunit 运行之前查找和解析任何 Javascript 文件。如果你让 Qunit 运行,它的错误处理程序会打印出你想要的带有语法错误的文件名。

唯一的解决方法是我描述的解决方法,或者修补 grunt-qunit-istanbul 以添加错误处理程序来解析错误,就像 Qunit 所做的那样。

修补 grunt-qunit-istanbul

抛出异常的函数是Instrumenter.instrumentSync,它应该这样做:

instrumentSync ( code, filename )

Defined in lib/instrumenter.js:380

synchronous instrumentation method. Throws when illegal code is passed to it

您可以通过包装函数调用来修复它:

diff -r 14008db115ff node_modules/grunt-qunit-istanbul/tasks/qunit.js
--- a/node_modules/grunt-qunit-istanbul/tasks/qunit.js  Tue Feb 25 12:14:48 2014 -0500
+++ b/node_modules/grunt-qunit-istanbul/tasks/qunit.js  Tue Feb 25 12:19:58 2014 -0500
@@ -209,7 +209,11 @@

       // instrument the files that should be processed by istanbul
       if (options.coverage && options.coverage.instrumentedFiles) {
-        instrumentedFiles[fileStorage] = instrumenter.instrumentSync(String(fs.readFileSync(filepath)), filepath);
+        try {
+          instrumentedFiles[fileStorage] = instrumenter.instrumentSync(String(fs.readFileSync(filepath)), filepath);
+        } catch (e) {
+          grunt.log.error(filepath + ': ' + e);
+        }
       }

       cb();

然后测试将继续运行(并通知您语法错误):

$ grunt qunit
Running "qunit:all" (qunit) task
>> /tmp/src/sample.js: Error: Line 2: Unexpected number
Testing testsSuites.html F.
>> global failure
>> Message: SyntaxError: Parse error
>> file:///tmp/src/sample.js:2

Warning: 1/2 assertions failed (19ms) Use --force to continue.

Aborted due to warnings.

【讨论】:

    【解决方案2】:

    我过去曾使用过 grunt-contrib-qunit,但我从未尝试过这样的事情。您面临的问题相当有趣,因为 docs 提到事件 qunit.error.onError 应该由 grunt 发出,但它不会发生在您身上。

    我使用 jquery 模板创建了一个新项目并更改了代码,这样我的测试就会失败。之后我写了以下代码:

    grunt.event.on('qunit.error.onError', function(message, stackTrace) {
      grunt.file.write('log/qunit-error.log', message);
    });
    

    当我运行命令grunt 时,我在文件中没有收到任何输出。为了检查这一点,我对事件进行了更改:

    grunt.event.on('qunit.log', function(result, actual, expected, message, source) {
      grunt.file.write('log/qunit-error.log', message);
    });
    

    现在,这段代码确实在我的文件中提供了错误消息,但它没有用,因为我无法获得堆栈跟踪或确切的错误消息。

    在此之后,我想阅读源代码,这就是我发现的:

    phantomjs.on('error.onError', function (msg, stackTrace) {
      grunt.event.emit('qunit.error.onError', msg, stackTrace);
    });
    

    只有当 phantomjs 抛出错误时才会发出 grunt 事件。

    目前我不确定如何在没有任何浏览器相关测试的情况下测试一个简单的 JavaScript 文件时出现 phantomjs 错误。这是我到目前为止的分析,希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多