qunit-tapを使ってnode.jsのテストをproveで行う - すぎゃーんメモ の続きです。
qunit-tapは1.0.0がreleaseされました。
https://github.com/twada/qunit-tap/commit/5da16418b6de71e4be186d080a0622e5689e8878
で、@t_wadaさんから追加情報をいただきました。
Node で qunit-tap を動かす際に、ちょっとだけ時間がかかるテストもきちんと通すためには QUnit.init(); の後に QUnit.config.updateRate = 0; が必要そうです。気づくのが遅れてすみません。エントリを修正していただけると嬉しいです
2011-03-28 19:59:24 via web
exports = module.exports = global; var path = require('path'); QUnit = require(path.join(path.dirname(require.resolve('qunit-tap')), '..', 'vendor', 'qunit', 'qunit', 'qunit')).QUnit; require("qunit-tap").qunitTap(QUnit, require("sys").puts, { noPlan: true }); QUnit.init(); exports.assert = QUnit;
とhelper scriptを用意している場合、
require('../test_helper.js'); QUnit.test('hoge', function() { assert.ok(true); }); QUnit.start();
のような単純なテストは問題ないですが
require('../test_helper.js'); QUnit.test('hoge', function() { for (var i = 0; i < 30000; i++) { assert.ok(true); } }); QUnit.start();
のように、時間のかかるテストを行うと、上手くいきません。
$ prove --ext=.js --exec=node t/hoge.js .. 29145/? node.js:134 throw e; // process.nextTick error, or 'error' event on first tick ^ TypeError: Object #<Object> has no method 'setTimeout' at process (/Users/sugyan/.nvm/v0.4.4/lib/node/.npm/qunit-tap/1.0.0/package/vendor/qunit/qunit/qunit.js:861:11) at Object.start (/Users/sugyan/.nvm/v0.4.4/lib/node/.npm/qunit-tap/1.0.0/package/vendor/qunit/qunit/qunit.js:412:4) at Object.<anonymous> (/Users/sugyan/temp/qunit-tap/t/hoge.js:9:7) at Module._compile (module.js:404:26) at Object..js (module.js:410:10) at Module.load (module.js:336:31) at Function._load (module.js:297:12) at Array.<anonymous> (module.js:423:10) at EventEmitter._tickCallback (node.js:126:26) t/hoge.js .. Dubious, test returned 1 (wstat 256, 0x100) All 30000 subtests passed Test Summary Report ------------------- t/hoge.js (Wstat: 256 Tests: 30000 Failed: 0) Non-zero exit status: 1 Parse errors: No plan found in TAP output Files=1, Tests=30000, 3 wallclock secs ( 2.27 usr 0.01 sys + 0.29 cusr 0.06 csys = 2.63 CPU) Result: FAIL
で、helper scriptで"QUnit.config.updateRate"を0にすると上手くいくようになります。
exports = module.exports = global; var path = require('path'); QUnit = require(path.join(path.dirname(require.resolve('qunit-tap')), '..', 'vendor', 'qunit', 'qunit', 'qunit')).QUnit; require("qunit-tap").qunitTap(QUnit, require("sys").puts, { noPlan: true }); QUnit.init(); QUnit.config.updateRate = 0; exports.assert = QUnit;
どうやらqunit.jsの中でこの設定値とテスト実行時間によって処理を切り分けているようで
while ( config.queue.length && !config.blocking ) { if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) { config.queue.shift()(); } else { window.setTimeout( process, 13 ); break; } }
十分に大きな値にしておくか、0以下にしておけば時間のかかるテストのときに問題が起こらなくなる…らしい。けど下の"setTimeout(process, 13)"ってなんだ…?マジックナンバー。。
蛇足
最初「時間がかかるテスト」がよくわからず
require('../test_helper.js'); QUnit.test('hoge', function() { setTimeout(function() { assert.ok(true); }, 1000); }); QUnit.start();
のようなのを書いていて「updateRateを設定しても動きません ><」となっていたんですが、QUnitで非同期のテストを書く場合はQUnit#stop と QUnit#start の組み合わせや、 QUnit#asyncTest を使うそうです。
require('../test_helper.js'); QUnit.asyncTest('hoge', function() { setTimeout(function() { assert.ok(true); QUnit.start(); }, 1000); }); QUnit.test('fuga' , function() { QUnit.stop(200); setTimeout(function() { assert.ok(true); QUnit.start(); }, 100); }); QUnit.start();
ちゃんとQUnitのドキュメント( http://docs.jquery.com/QUnit/asyncTest あたり? )とか読むべきですね。