こんにちは!ishiBです。
今回はJavascriptのテストフレームワーク「Jasmine」を紹介します。
Jasmineは、RSpec(http://rspec.info/)に近い記法を使ってJavaScriptのテスティングを行うフレームワークです。
Jasmineは(https://github.com/pivotal/jasmine/downloads)からダウンロードできます。
では早速実際にJasmineを使って、テストをしてみたいと思います。
ファイルの構成は以下のようになっています。

ダウンロードしたファイルにはサンプルファイルも入っているので、今回はそれをもとに説明していきたいと思います。
それではソースの中身を見ていきましょう。
テスト対象クラスは以下のようになっています。
[javascript]
function Player() {
}
Player.prototype.play = function(song) {
this.currentlyPlayingSong = song;
this.isPlaying = true;
};
Player.prototype.pause = function() {
this.isPlaying = false;
};
Player.prototype.resume = function() {
if (this.isPlaying) {
throw new Error("song is already playing");
}
this.isPlaying = true;
};
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
[/javascript]これに対するテストクラスは以下のように記述します。
[javascript]
// `describe`メソッドにクラス等のテスト対象を記述します。
describe("Player", function() {
var player;
var song;
beforeEach(function() {
player = new Player();
song = new Song();
});
// `it`メソッドにテスト実施内容を記述します。
it("should be able to play a Song", function() {
// テスト内容を記述します。
player.play(song);
// 期待値との比較を行います。
expect(player.currentlyPlayingSong).toEqual(song);
// 期待値との比較を複数回行うことができます(一つでも期待値に一致しない場合はNG)。
expect(player).toBePlaying(song);
});
// `describe`メソッドの中に`describe`メソッドを追加することもできます。
describe("when song has been paused", function() {
beforeEach(function() {
player.play(song);
player.pause();
});
// 上記と同じように`it`メソッドにテスト内容を記述します。
it("should indicate that the song is currently paused", function() {
expect(player.isPlaying).toBeFalsy();
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
it("should be possible to resume", function() {
player.resume();
expect(player.isPlaying).toBeTruthy();
expect(player.currentlyPlayingSong).toEqual(song);
});
});
// demonstrates use of spies to intercept and test method calls
it("tells the current song if the user has made it a favorite", function() {
spyOn(song, 'persistFavoriteStatus');
player.play(song);
player.makeFavorite();
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
});
//demonstrates use of expected exceptions
describe("#resume", function() {
it("should throw an exception if song is already playing", function() {
player.play(song);
// 異常系のテストは以下のように記述します。
expect(function() {
player.resume();
}).toThrow("song is already playing");
});
});
});
[/javascript]※1 日本語のコメントは後から追加しました。
このテストを実行してみます。
SpecRunner.htmlは以下のように記述します。
[html]</pre>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.2.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.2.0/jasmine.css">
<script type="text/javascript" src="lib/jasmine-1.2.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-1.2.0/jasmine-html.js"></script>
<!-- テストファイルを読み込みます -->
<script type="text/javascript" src="spec/SpecHelper.js"></script>
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
<!-- テスト対象ファイルを読み込みます -->
<script type="text/javascript" src="src/Player.js"></script>
<script type="text/javascript" src="src/Song.js"></script>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body></body>
</html>
[/html]実行結果

すべてのテストが成功しました。
エラーがある場合は以下のように表示されます。
・実行結果一覧画面(エラーのテストは赤字で表示されます)

・実行詳細画面

このように簡単にJavascriptのテストが実施できます。
今回の説明では詳しく触れませんが、Jasmineは非同期な動作もテストすることが出来ます。
またCI(継続的インテグレーション)に統合することも可能です。
興味のある方は参考にしてみてください。
ではでは~


