Mochaと
Chaiを使ってブラウザサイド単体テストをやってみる。
この記事では環境構築、同期処理のテスト、非同期処理のテスト、jQuery Deferredのテストの基本のみ扱う。
環境
環境構築
本記事では、Mocha、ChaiやjQueryをCDNから直接使うため、特に何かをダウンロードする必要はなく、
例えば以下のようなディレクトリ構成で各ファイルを作成すれば大丈夫。
.
├── spec
│   ├── main_spec.js
│   └── spec_runner.html
└── src
└── main.js
2 directories, 3 files
同期処理のテスト
ものすごく単純に下記の関数をテストする場合を考える。
function double(n) {
if(!n) {
throw new Error("no param");
} else {
return n * n;
}
}
この関数に対するテストコードはBDDスタイルで下記のように書ける。
describe('SampleTest', function(){
describe('Test Double Func', function(){
it('should return double value', function(){
expect(double(2)).to.equal(4); //except assertion
double(3).should.equal(9); //should assertion
});
it('should throw error undefined without param', function(){
expect(function() { double() }).to.throw("no param");
});
});
});
ブラウザで単体テストを実行させるにはspec_runnerというHTMLファイルを作成する必要がある。
この中で、mocha・chaiや先ほど作成したmain.jsとmain_spec.jsを読み込む。
mocha・chaiの設定もここに記載する。
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<script type="text/javascript" src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.1.0/chai.js"></script>
<script>
mocha.setup('bdd')
var assert = chai.assert;
var expect = chai.expect;
chai.Should();
</script>
<script src="../src/main.js"></script>
<script src="./main_spec.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
</script>
</body>
</html>
main.js、main_spec.js、spec_runner.htmlの3つのファイルが作成できたら、
spec_runner.htmlをダブルクリックで起動して結果を確認する。
以下のような画面になっていたら、テストをパスしたことになる。
失敗する場合は赤文字で各ケースの下にエラーメッセージが表示される。
非同期処理のテスト
javascriptではコールバックを含む処理が頻出する。
そういった関数をテストする場合は下記のようにすれば良い。
function doubleAsync(n, callback) {
setTimeout(function(){
callback(n * n);
}, 100);
}
describe('Test DoubleAsync Func', function(){
it('should return double value', function(done){
doubleAsync(2, function(result){
result.should.equal(4);
done();
});
});
});
非同期処理に対するテストコードではdoneが必須である。
これを忘れると永久に処理は終わらない。
spec_runner.htmlは変更する必要はない(ファイル名を変更した場合は、読み込むファイル名を変更する必要がある)。
先ほどと同じようにダブルクリックでspec_runner.htmlを起動すると今度は以下のように、かかった時間が表示される。
jQuery Deferred
jQuery Deferredを使った場合も基本的には非同期処理と同じようにすればいい。
テスト対象のコードとして今度は以下の様な関数を考える。
function api_data() {
var deferred = jQuery.ajax({
url: "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20140222?format=json&keyword=%E6%A5%BD%E5%A4%A9&genreId=559887&shopCode=rakuten24&applicationId=#{Please input your id}",
dataType: "jsonp"
})
.done(function(items) {})
.fail(function(error) {})
return deferred;
}
これは
楽天商品検索APIの結果を取得するコードである。この関数をテストする場合は以下のようにalwaysを使えば良い。
describe('SampleTest', function(){
describe('API Data Func', function(){
it('should return correct dada', function(done){
api_data().always(function(result) {
expect(result['page']).to.equal(1);
done();
});
});
});
});
jQueryを読み込む必要があるため、spec_runner.htmlを以下のように変更する。
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<script src="https://cdn.rawgit.com/jquery/jquery/2.1.4/dist/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.1.0/chai.js"></script>
<script>
mocha.setup('bdd')
var assert = chai.assert;
var expect = chai.expect;
chai.Should();
</script>
<script src="../src/main3.js"></script>
<script src="./main_spec3.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['jQuery*']);
mocha.run();
</script>
</body>
</html>
mocha.globalsの”jQuery*”がポイント。これがないとたとえば以下のようなエラーが出てしまう。
Mochaに対してグローバル変数名をあらかじめ提示しないとエラーになってしまう。
今回のコードで利用しているグローバル変数は”jQuery”とjsonpで利用する”jQuery[0-9]+”である。
jsonpで利用する方は毎回番号が変わってしまうため、両方指定するには”jQuery*”とする必要がある。
正しく設定すれば以下のような結果になる。