まだベータ段階なので、遊び程度で使うのが丁度いい
$ npm install -g buster
buster.js
)ファイルを作成browser
or node
を指定できる(ハイブリッドも可能)buster server
でローカルサーバを起動$ buster test
でconfigを元にファイルを読み込んでテストを実行 QUnitやJasmineのように静的なHTMLとしてテストを実行する$ buster static
もあります
否定のassertionsの書き方が違う。
BusterJSはrefute
メソッドを使う
// JsTestDriver
assertNoException(function () {
something()
});
// BusterJS
refute.exception(function(){
somthing();
});
引数の順番が違う事がある
// JsTestDriver
assertClassName("js-tab-controller", this.tabs);
// BusterJS
assert.className(this.tabs, "js-tab-controller");
BusterJSはドキュメントが多い
設定ファイルもJavaScriptで定義する(buster.js
というファイル名がよく使われる)
var config = module.exports;
config["My tests"] = {
env: "browser", // or "node"
sources: [
"lib/mylib.js", // Paths are relative to config file
"src/**/*.js" // Glob patterns supported
],
tests: [
"test/*-test.js"
]
}
"テスト名" : function(){ /* test code */ }
strtime test
buster.testCase("Date strftime test", {
setUp: function () {
this.date = new Date(2009, 2, 11);
},
"%Y should be '2009'": function () {
assert.equals(this.date.strftime("%Y"), "2009");
},
"%y should be '09'": function () {
assert.equals(this.date.strftime("%y"), "09");
},
// ...
});
assertとrefute以下にそれぞれ同じ用途のメソッドが入ってる
assert(true);// PASS
refure(false);// PASS
assert.same("a","a");// PASS
refute.same(1,"1");//===で比較するとfalseなので PASS
e.g)
buster.spec.expose(); // describe/it/itEventually/before/afterがグローバルに定義される
describe("A module", function () {
it("states the obvious", function () {
expect(true).toEqual(true);
});
});
ネストしたtestCase
buster.testCase("Nested setup and teardown call order", {
setUp : function(){
buster.console.log("Setup #1") ;
},
tearDown : function(){
buster.console.log("Teardown #1");
},
"test #1" : function(){
buster.console.log("Test #1");
},
"context" : {
setUp : function(){
buster.console.log("Setup #2");
},
"test #2" : function(){
buster.console.log("Test #2");
},
"context" : {
setUp : function(){
buster.console.log("Setup #3");
},
tearDown : function(){
buster.console.log("Teardown #3");
},
"//test #3" : function(){
buster.console.log("Test #3");
}
}
}
});
// から始まるテストは✎(コンソールだと-)となり実行されずに保留される
✎ Nested setup and teardown call order context context test #3
✓ Nested setup and teardown call order context test #2
[LOG] Setup #1 // <= ネストの親
[LOG] Setup #2
[LOG] Test #2
[LOG] Teardown #1 // <= ネストの親
✓ Nested setup and teardown call order test #1
[LOG] Setup #1
[LOG] Test #1
[LOG] Teardown #1
1 test case, 2 tests, 2 assertions, 0 failures, 0 errors, 0 timeouts, 1 deferred
buster.log()
を使う。buster.console.log()
も同等
jstestdriver.console.log()
に類似するコンソール出力用API
buster.log(buster.console);
// => コンソールにフォーマットされて出力される
[LOG] {
contexts: { log: [undefined] },
debug: function () {},
error: function () {},
format: function () {},
level: "debug",
levels: ["error", "warn", "log", "debug"],
listeners: { log: [function () {}] },
log: function () {},
logFunctions: true,
warn: function () {}
}
buster.log()
はpretty printされた形で出力される
var fn = function innerFn(){
doSomthing();
};
var obj = {"a" : 1, b : {b1 : "in"}, c : [1, 2, 3]};
buster.log(fn, "\n", obj);
[LOG] function innerFn() {}
{ a: 1, b: { b1: "in" }, c: [1, 2, 3] }
Buster.JS core modulesのbuster.formatを使って整形処理が行われている
$ buster test -h reporters
実行結果をどういう形式で出力するかを決定できる. 独自の出力形式もJavaScriptで比較的簡単に作成できる
テストケースにそのまま非同期コードを書くと、assertされる前にテストが終わってします
"test not asynchronous" : function(){
setTimeout(function(){
assert(true);
}, 100);
}
✖ My thing test not asynchronous
No assertions!
正しいやり方の例
"test asynchronous" : function(done){
setTimeout(function(){
assert(true);
done();
}, 100);
}
✓ My thing test asynchronous
Promissオブジェクトをテストケースで返して非同期テストを行う
"test async, use promiss" : function(){
var promise = { // then メソッドの有無が重要
then : function(callback){
this.callbacks = this.callbacks || [];
this.callbacks.push(callback);
}
};
setTimeout(function(){
buster.assert(true);
var callbacks = promise.callbacks || [];
for (var i = 0, l = callbacks.length; i < l; ++i){
callbacks[i]();
}
}, 100);
// thenを持ったものを返す => promissと判断 (isPromise)
return promise;
}
When.js を使って先ほどと同じ非同期テストを書くと
"test async ,use when.js" : function(){
var deferred = when.defer();
setTimeout(function(){
buster.assert(true);
deferred.resolver.resolve();
}, 100);
return deferred.promise;
}
assertionにはSinon.jsと連動したものもいくつか含まれている。
"test should call all observers" : function(){
var spy1 = sinon.spy();
this.observable.observe(spy1);
this.observable.notify();
assert.called(spy1);
}
buster.js ...
"resources" : [
{// testbed
"path" : "/",
"file" : "fixtures/testbed.html",
"headers" : {
"Content-Type" : "text/html"
}
},
{// JSON APIのモック
"path" : "/res.json",
"content" : JSON.stringify({
text : "テキストー",
id : 4
}),
"headers" : {
"Content-Type" : "application/json"
}
}
]
Configのextensionsプロパティで必要な拡張を読み込む
var config = module.exports;
config["Browser tests"] = {
rootPath: "../",
sources: ["src/**/*.js"]
tests: ["test/**/*.js"],
extensions: [require("buster-jstestdriver")]
};
:DOC
形式コメントもサポートWebStormの場合
BusterJSの構文についてのJSDocファイル
/**
* Fails if actual is falsy (0, "", null, undefined, NaN).
* @param actual actual is falsy (0, "", null, undefined, NaN)
* @param [message]
*/
buster.assertions.assert = function assert(actual, message){}
/**
* Fails if actual is not the same object (===) as expected
* @param expected
* @param actual
* @param [message]
*/
buster.assertions.assert.same = function same(expected, actual, message){}
Webstormの Settings -> JavaScript ->Libraries -> から参照する事でBusterJSのメソッドを補完候補に追加できる
選択したディレクトリでbuster server
を実行する
Program: /Users/azu/.nodebrew/current/bin/node
Parameter: /Users/azu/.nodebrew/current/bin/buster-server
Working Directory: $FileDir$
BusterJSのキャプチャURLを開くだけ
Program: /usr/bin/open
Parameter: http://localhost:1111/capture
選択してるテストファイルを実行する
Program: /Users/azu/.nodebrew/current/bin/node
Parameter: /Users/azu/.nodebrew/current/bin/buster-test --reporter specification -t $FilePath$
Working Directory: $FileDir$
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |