連載
» 2012年11月29日 18時00分 公開

フレームワークで実践! JavaScriptテスト入門(3):QUnit+PhantomJSでJavaScriptのヘッドレスなテスト (2/3)

[朝香貴寛,TIS コーポレート本部 戦略技術センター]

QUnitでテストを実行してみよう

 それでは、実際にQUnitでテストを実行してみます。QUnitの導入はとても簡単です。QUnitの公式ページから「qunit-1.10.0.js」「qunit-1.10.0.css」をダウンロードし、以下のようにテスト用HTML「index.html」からテスト対象コード「target.js」とテストコードtests.jsと一緒に読み込むだけです。

index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>QUnit Example</title>
  <link rel="stylesheet" href="./resources/qunit-1.10.0.css">
</head>
<body>
  <div id="qunit"></div>
  <script src="./resources/qunit-1.10.0.js"></script>
  <script src="./resources/target.js"></script>
  <script src="./resources/tests.js"></script>
</body>
</html>

 HTMLファイルが準備できたら、先ほど例で挙げたテストコードをtests.jsに記述し実行してみましょう。

tests.js
module("syncTest");
test("syncFuncTest", 1, function(){
    equal("hello, world!", syncFunc(), "return to expected data");
});
module("async");
test("asyncFuncTest", function(){
    expect(2);
    stop();
    asyncFunc(function(message){
        start();
        ok(true, "call to callback function");
        equal("hello, world!", message, "return to expected data");
    });
});

 index.htmlをWebブラウザで開くとテストが実行され、以下のような結果が表示されると思います。

QUnit実行結果(【失敗】1)

 表示されているテスト結果の「(1, 0, 1)」「(2, 0, 2)」は前から、失敗したテスト数、成功したテスト数、全テスト数を示しています。

equalアサーションで失敗した場合

 テストの実行が確認できたので、次はテストがErrorで失敗するのではなく、equalアサーションで失敗した場合にどんな表示になるかも確認してみます。asyncFunc関数は非同期処理ということで、今回は簡単にsetTimeoutで実装します。

テストが失敗するtarget.jsの例
function syncFunc(){
    return "hello!";
}
  
function asyncFunc(callback){
    setTimeout(function(){
        callback("world!");
    }, 500);
}
QUnit実行結果(【失敗】2)

 このようにequalアサーションで失敗すると、結果だけではなくexpectedとresultを確認できます。

全てのテストを成功させた場合

 失敗内容が確認できたので、target.jsを修正し、全てのテストを成功させます。

テストが成功するtarget.jsの例
function syncFunc(){
    return "hello, world!";
}
 
function asyncFunc(callback){
    setTimeout(function(){
        callback("hello, world!");
    }, 500);
}
QUnit実行結果(【成功】)

PhantomJSを使ってWebブラウザなしでテストを実行

 QUnitを実行する環境が整ったところで、今回の目的であるPhantomJSを使ってWebブラウザなしでテストを実行できるようにします。PhantomJSのインストールは前回の記事を参照してください。

 前回のPhantomJS+Jasmineと同様に、PhantomJSにはQUnit用テストランナーのサンプルコードが用意されています。また、QUnitの方でもアドオンとしてPhantomJSのテストランナーのサンプルコードが用意されています。

 PhantomJSのランナーはダウンロードしてきたディレクトリの「phantomjs/examples/run-qunit.js」(run-qunit.coffeeも同様)、QUnitのランナーはGitHubの「https://github.com/jquery/qunit/blob/master/addons/phantomjs/runner.js」にあります。

 PhantomJSとテストランナーが準備できたら、先ほどWebブラウザで実行した1件失敗するテストを実行してみます。

PhantomJSで提供されているテストランナーでの実行結果
$ phantomjs phantomjs/examples/run-qunit.js index.html
'waitFor()' finished in 1200ms.
Tests completed in 1035 milliseconds.
4 tests of 5 passed, 1 failed.
QUnitで提供されているテストランナーでの実行結果
$ phantomjs runner.js index.html 
Assertion Failed: async: asyncFunc
    Failed assertion: call to callback function
Took 1035ms to run 5 tests. 4 passed, 1 failed.

URLを指定して公開されているテストを実行

 また、どちらのテストランナーもURLを指定可能なので、Webサーバで公開されているテストも実行できます。試しに、公開されているjQueryのcoreモジュールのテストを実行してみると以下のようになります。

PhantomJSで提供されているテストランナーでの実行結果
$ phantomjs phantomjs/examples/run-qunit.js http://swarm.jquery.org/build/jquery/53cb49cb0a9696c887b91547ac1259c5b860bece/test/index.html?module=core
'waitFor()' finished in 759ms.
Tests completed in 858 milliseconds.
382 tests of 383 passed, 1 failed.
QUnitで提供されているテストランナーでの実行結果
$ phantomjs runner.js http://swarm.jquery.org/build/jquery/53cb49cb0a9696c887b91547ac1259c5b860bece/test/index.html?module=core
Assertion Failed: core: jQuery.parseXML
    Failed assertion: invalid xml not detected
Took 852ms to run 383 tests. 382 passed, 1 failed.

余談「QtWebKitのDOMParserの実装」

 指定したURLのテストはChromeなどのWebブラウザで確認すると全て通っているのですが、PhantomJSでテストすると、不正なxmlをparseした際にerrorがthrowされ、「try-catchでcatchすることを確認する」テストが失敗します。


 これはjQuery.parseXML関数内で使われているDOMParserの実装がQtWebKitでは異なるようで、「<<」という文字を含んだxmlをparseした場合はerrorがthrowされないことが原因のようです。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。