Jasmine
- HTML5 APIs
- UI ライブラリ
- テスト支援
- ドキュメント
- コード品質ツール
- バリデータ
- キー入力支援
- テストダブル
- ハイブリッドアプリケーション
- 継続的インテグレーション
Jasmineについて
ダウンロードはgithubのリリースページから可能です
jasmine - github
Jasmineを使ったテストの記述
Jasmineのテスト記述のサンプルです。
<html>
<head>
<meta charset="UTF-8">
<!-- jasmine読み込み -->
<link rel="stylesheet" href="lib/jasmine-2.3.4/jasmine.css" />
<script src="lib/jasmine-2.3.4/jasmine.js"></script>
<script src="lib/jasmine-2.3.4/jasmine-html.js"></script>
<!-- jasmine実行スタート -->
<script src="lib/jasmine-2.3.4/boot.js"></script>
<!-- テスト対象コード -->
<script src="sample/util.js"></script>
<!-- テストコード -->
<script src="test.js"></script>
</head>
<body>
</body>
</html>
(function(){
describe('util.plus()', function(){
it('plusの計算結果が正しいこと', function(){
expect(util.calc(1, 2)).toBe(3);
});
it('引数が3つ以上の場合の結果が正しいこと', function(){
expect(util.calc(1, 2, 3)).toBe(6);
expect(util.calc(1, 2, 3, 4)).toBe(10);
});
});
});
describe()で定義する単位をテストスイート、it()で定義する単位をテストスペックと言います。
テストスイートの中にテストスペックを複数記述することができます。
またテストスペックの中に複数のexpect文を記述できます。全てのexpect文が正しければそのテストスペックは成功となります。
スイートの入れ子
テストスイートは入れ子にすることが可能です。
describe('util.plus()', function(){
it('plusの計算結果が正しいこと', function(){
expect(util.calc(1, 2)).toBe(3);
});
describe('util.minus()', function(){
it('minusの計算結果が正しいこと', function(){
expect(util.calc(1, 2)).toBe(-1);
});
});
});
非同期テストの記述
it()の第2引数にテスト実行関数を渡しますが、その関数で引数を取るようにする(=仮引数を記述する)とそのテストは非同期になります。
引数には次のテストを呼び出すための関数が渡され、それを呼ぶとテストが終了します。
describe('util.getData()', function(){
it('データが取得できること', function(done){
var promise = util.getData();
promise.done(function(data){
expect(data).toBeTruthy();
}).fail(function(){
expect(data).toBeTruthy();
}).always(done); // 非同期処理が終了したら引数に渡されるdoneを呼ぶ
});
});
テスト実行前後の処理
beforeEach/afterEach
スペック(it())の前後の処理を記述します。it()と同様に非同期にすることもできます。
beforeAll/afterAll
スイート(describe())の前後に実行する処理を記述します。it()と同様に非同期にすることもできます。
thisについて
テスト実行中のthisにはテストスペック中のコンテキストオブジェクトが格納され、デフォルトはただの空オブジェクトです。テストスペック中のコンテキストオブジェクトはbefore/afterでも同じオブジェクトを参照しています。
以下、before/afterを使用したテストコードのサンプルです。
beforeAll(function(done){
// 'sample.controller'のスイート開始時に行う処理
// コントローラのバインド。非同期。
var controller = h5.core.controller('.target', sample.controller);
// コンテキストオブジェクトに生成したコントローラを格納
this.controller = controller;
controller.readyPromise.done(done);
});
afterAll(function(){
// 'sample.controller'のスイート終了時に行う処理
controller.dispose();
});
beforeEach(function(){
// 'sample.controller'のスイート内の各スペック開始時に行う処理
this.controller.refresh();
});
it('methodA', function(){
expect(this.controller.methodA()).toBe(true);
});
it('methodB', function(){/* ... */});
});
テストの開始
テストの開始処理は、Jasmineパッケージに含まれるboot.jsに記述されています。boot.jsではテスト結果をHTMLとして出力するためのHTMLレポータ(レポータについては後述)の初期設定や、specFilter設定(後述)、を行った後にテストを開始する処理が記述されています。
追加したいレポータや、テスト開始前に行いたい処理がある場合はboot.jsをカスタマイズまたは自分で1からテスト開始前の処理及びテスト開始処理を記述します。
テストを開始するには以下のように記述します。
// ここではwindow.onloadのタイミングで実行している
window.addEventListener('load', function(){
var env = jasmine.getEnv();
env.execute();
});
レポータ
Jasmineでは以下のタイミングでコールバックを登録することが出来ます。
- jasmineStart
テスト全体を実行する直前 - jasmineDone
テスト全体が完了 - specStart
テストスペック開始直前 - specDone
テストスペック終了直後 - suiteStart
テストスイート開始直前 - suiteDone
テストスイート終了直後
テスト実行中のコールバック処理を行うためのクラスをレポータと言います。
以下のコードはレポータを作成してJasmineに登録するサンプルコードです。MyReporterというレポータを作成してJasmineに登録しています。
MyReporter.prototype.jasmineStart = function(){ /* ... */ };
MyReporter.prototype.specStart = function(){ /* ... */ };
var env = jasmine.getEnv();
var myReporter = new MyReporter();
// コールバック関数を実装するクラス(レポーター)をaddReporterで追加
env.addReporter(myReporter);
上記例ではレポータクラスを作ってaddReporterで追加していますが、単純なオブジェクトでも動作します。
jasmineStart: function(){...},
specStart: function(){...}
});
なお、Jasmineパッケージに含まれるjasmine-html.jsはテスト結果をHTMLに出力するHTMLレポータが定義されています。同じくJasmineパッケージに含まれるboot.jsではHTMLレポータの設定と登録をする処理が含まれています。
スペックフィルタ
テスト実行開始時に全スペック(it())について実行するかしないか、スキップするかしないかを設定することができます。
スペックフィルタの設定は以下のように行います。テスト実行開始前に記述する必要があります。
env.specFilter = function(spec){
var specName = spec.description; // スペック名。it()の第1引数
var fullName = spec.getFullName(); // 親(祖先)スイート名とスペック名を半角スペース区切りで連結したフルネーム
var specId = spec.id; // 勝手に振られるスペックのID。"spec0"のような文字列。
// スキップする場合
// spec.pend(message);
// 実行する場合
// return true;
// 実行させない場合
// return false;
// もしくは何も返さない
}