QUnit & jQuery でイベント起動処理のテストを行う
QUnitを使ったイベント起動処理のテスト方法について書く。
jQueryを使うことを前提とする。
1. 今回のテスト対象
簡単な例として、「四角形をクリックすると動く」だけのコードをテスト対象とする。
2. QUnit実行htmlファイル作成
テスト対象のコードがQUnit実行htmlファイル上で動くようにする。
そのため、今回の例では以下を追加している。
・テスト対象のコードが参照するCSSを記述
・テスト対象のコードが使用する要素<div id="root"></div>を記述
追加箇所を赤字にした。
なお、simpleAnime.jsがテストの対象コード、simpleAnimeTest.jsが以下で解説するテストコード。
3. テストコード作成
作成した以下のテストコードについて解説する。
3.1 $(document).ready のテスト
asyncTest('waif for ready', ...)で、$(document).readyで指定した処理が終わるまで待つ。
asyncTest()については、[QUnit] asyncTest() および stop() を簡単に解説 で解説している。
$(document).readyの処理が終わってからテストコードが動くようにするため、最後の処理が実行されることを確認してからstart()することが望ましい。
今回の例では「クリックイベントが付与されたこと」を確認するのが望ましいのだが、簡単にできそうにないので「四角形が追加されたこと」を確認している。
($box.data('events') でセットされているイベントハンドラを参照できるのだが、jQuery内部で使用しているデータでAPIとしては提供されていない)
その後のtest('boxdiv', ...)で、$(document).readyの処理結果をチェックしている。
3.2 クリックイベントのテスト
asyncTest('movebox 1', ...)およびasyncTest('movebox 2', ...)内でクリックイベントを発行して、イベント起動処理が終わるまで待つ。
$(document).readyと同様、最後の処理が実行されることを確認してからstart()することが望ましい。
今回の例では「右(または左)に動いたこと」をチェックするだけなので、asyncTest()内でテストが完結している。必要であれば後続に処理結果チェック用のtest()を追加する。
3.3 テストコード作成時の注意事項
asyncTest()およびtest()外に記述されたコードは、start()を待たずに即実行される。
そのため、テストコードはasyncTest()およびtest()内に記述すること。
以上。
<関連エントリ>
QUnit+jQueryで、チンチロリンゲーム自動実行テストプログラムを作った
jQueryを使うことを前提とする。
1. 今回のテスト対象
簡単な例として、「四角形をクリックすると動く」だけのコードをテスト対象とする。
/* boxをクリックすると動く */
var mvb = {}; // namespace
/* 定数 */
mvb.con = {
rootid: 'root', // rootdivのid
boxid: 'box1', // boxのid
boxtop: 20, // boxのcss top
boxleft: 20, // boxのcss left初期値
boxmvlen: 200, // boxの移動距離(px)
boxclsnm: 'boxdiv', // boxのcss classname
bgcol: 'rgb(51,153,255)' // boxの背景色
};
/* boxを移動 */
mvb.movebox = function() {
var $box = $(this);
var afterleft; // 移動後のleft
if ($box.css('left') == mvb.con.boxleft + 'px') {
afterleft = mvb.con.boxleft + mvb.con.boxmvlen;
} else {
afterleft = mvb.con.boxleft;
}
$box.animate({left: afterleft});
};
$(document).ready(function() {
// boxを作成し、rootdivに追加
var $box = $('<div/>').attr('id', mvb.con.boxid)
.addClass(mvb.con.boxclsnm)
.css('backgroundColor', mvb.con.bgcol)
.css('top', mvb.con.boxtop).css('left', mvb.con.boxleft);
$('#' + mvb.con.rootid).append($box);
// イベント付与
$box.click(mvb.movebox);
});
var mvb = {}; // namespace
/* 定数 */
mvb.con = {
rootid: 'root', // rootdivのid
boxid: 'box1', // boxのid
boxtop: 20, // boxのcss top
boxleft: 20, // boxのcss left初期値
boxmvlen: 200, // boxの移動距離(px)
boxclsnm: 'boxdiv', // boxのcss classname
bgcol: 'rgb(51,153,255)' // boxの背景色
};
/* boxを移動 */
mvb.movebox = function() {
var $box = $(this);
var afterleft; // 移動後のleft
if ($box.css('left') == mvb.con.boxleft + 'px') {
afterleft = mvb.con.boxleft + mvb.con.boxmvlen;
} else {
afterleft = mvb.con.boxleft;
}
$box.animate({left: afterleft});
};
$(document).ready(function() {
// boxを作成し、rootdivに追加
var $box = $('<div/>').attr('id', mvb.con.boxid)
.addClass(mvb.con.boxclsnm)
.css('backgroundColor', mvb.con.bgcol)
.css('top', mvb.con.boxtop).css('left', mvb.con.boxleft);
$('#' + mvb.con.rootid).append($box);
// イベント付与
$box.click(mvb.movebox);
});
2. QUnit実行htmlファイル作成
テスト対象のコードがQUnit実行htmlファイル上で動くようにする。
そのため、今回の例では以下を追加している。
・テスト対象のコードが参照するCSSを記述
・テスト対象のコードが使用する要素<div id="root"></div>を記述
追加箇所を赤字にした。
なお、simpleAnime.jsがテストの対象コード、simpleAnimeTest.jsが以下で解説するテストコード。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>イベント起動処理のテスト</title>
<style TYPE="text/css">
.rootdiv {
position: relative;
}
.boxdiv {
display: block;
position: absolute;
width: 100px;
height: 100px;
border-style: solid;
border-width: 2px;
border-color: #808080;
}
</style>
<link rel="stylesheet" href="./qunit/qunit.css" type="text/css" media="screen">
<script type="text/javascript" src="jquery.js" charset="UTF-8"></script>
<script type="text/javascript" src="simpleAnime.js" charset="UTF-8"></script>
<script type="text/javascript" src="./qunit/qunit.js" charset="UTF-8"></script>
<script type="text/javascript" src="simpleAnimeTest.js" charset="UTF-8"></script>
</head>
<body>
<h1 id="qunit-header">QUnit Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup</div>
<div id="root"></div>
</body>
</html>
<html>
<head>
<meta charset="UTF-8" />
<title>イベント起動処理のテスト</title>
<style TYPE="text/css">
.rootdiv {
position: relative;
}
.boxdiv {
display: block;
position: absolute;
width: 100px;
height: 100px;
border-style: solid;
border-width: 2px;
border-color: #808080;
}
</style>
<link rel="stylesheet" href="./qunit/qunit.css" type="text/css" media="screen">
<script type="text/javascript" src="jquery.js" charset="UTF-8"></script>
<script type="text/javascript" src="simpleAnime.js" charset="UTF-8"></script>
<script type="text/javascript" src="./qunit/qunit.js" charset="UTF-8"></script>
<script type="text/javascript" src="simpleAnimeTest.js" charset="UTF-8"></script>
</head>
<body>
<h1 id="qunit-header">QUnit Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup</div>
<div id="root"></div>
</body>
</html>
3. テストコード作成
作成した以下のテストコードについて解説する。
/* simpleAnime.js のテスト
* jquery.js を前提としている
*/
var timeoutID;
module('$(document).ready');
asyncTest('waif for ready', 1, function() {
timeoutID = window.setInterval(function() {
if ( $('#' + mvb.con.boxid).length > 0) {
ok(true, 'box has appended.');
window.clearTimeout(timeoutID);
start();
}
}, 100);
});
test('boxdiv', 4, function() {
var $box = $('#' + mvb.con.boxid);
strictEqual($box.hasClass(mvb.con.boxclsnm), true, 'classname');
equal($box.css('backgroundColor').replace(/\s/g, ''), mvb.con.bgcol,
'backgroundColor');
equal($box.css('top'), mvb.con.boxtop + 'px', 'css top');
equal($box.css('left'), mvb.con.boxleft + 'px', 'css left');
});
module('mvb.movebox');
asyncTest('movebox 1', 1, function() {
// boxの位置を初期値にする
var $box = $('#' + mvb.con.boxid);
$box.css('left', mvb.con.boxleft);
$box.click();
timeoutID = window.setInterval(function() {
if ( $box.css('left') == (mvb.con.boxleft + mvb.con.boxmvlen) + 'px') {
ok(true, 'box moved left.');
window.clearTimeout(timeoutID);
start();
}
}, 100);
});
asyncTest('movebox 2', 1, function() {
var $box = $('#' + mvb.con.boxid);
$box.click();
timeoutID = window.setInterval(function() {
if ( $box.css('left') == mvb.con.boxleft + 'px') {
ok(true, 'box moved right.');
window.clearTimeout(timeoutID);
start();
}
}, 100);
});
* jquery.js を前提としている
*/
var timeoutID;
module('$(document).ready');
asyncTest('waif for ready', 1, function() {
timeoutID = window.setInterval(function() {
if ( $('#' + mvb.con.boxid).length > 0) {
ok(true, 'box has appended.');
window.clearTimeout(timeoutID);
start();
}
}, 100);
});
test('boxdiv', 4, function() {
var $box = $('#' + mvb.con.boxid);
strictEqual($box.hasClass(mvb.con.boxclsnm), true, 'classname');
equal($box.css('backgroundColor').replace(/\s/g, ''), mvb.con.bgcol,
'backgroundColor');
equal($box.css('top'), mvb.con.boxtop + 'px', 'css top');
equal($box.css('left'), mvb.con.boxleft + 'px', 'css left');
});
module('mvb.movebox');
asyncTest('movebox 1', 1, function() {
// boxの位置を初期値にする
var $box = $('#' + mvb.con.boxid);
$box.css('left', mvb.con.boxleft);
$box.click();
timeoutID = window.setInterval(function() {
if ( $box.css('left') == (mvb.con.boxleft + mvb.con.boxmvlen) + 'px') {
ok(true, 'box moved left.');
window.clearTimeout(timeoutID);
start();
}
}, 100);
});
asyncTest('movebox 2', 1, function() {
var $box = $('#' + mvb.con.boxid);
$box.click();
timeoutID = window.setInterval(function() {
if ( $box.css('left') == mvb.con.boxleft + 'px') {
ok(true, 'box moved right.');
window.clearTimeout(timeoutID);
start();
}
}, 100);
});
3.1 $(document).ready のテスト
asyncTest('waif for ready', ...)で、$(document).readyで指定した処理が終わるまで待つ。
asyncTest()については、[QUnit] asyncTest() および stop() を簡単に解説 で解説している。
$(document).readyの処理が終わってからテストコードが動くようにするため、最後の処理が実行されることを確認してからstart()することが望ましい。
今回の例では「クリックイベントが付与されたこと」を確認するのが望ましいのだが、簡単にできそうにないので「四角形が追加されたこと」を確認している。
($box.data('events') でセットされているイベントハンドラを参照できるのだが、jQuery内部で使用しているデータでAPIとしては提供されていない)
その後のtest('boxdiv', ...)で、$(document).readyの処理結果をチェックしている。
3.2 クリックイベントのテスト
asyncTest('movebox 1', ...)およびasyncTest('movebox 2', ...)内でクリックイベントを発行して、イベント起動処理が終わるまで待つ。
$(document).readyと同様、最後の処理が実行されることを確認してからstart()することが望ましい。
今回の例では「右(または左)に動いたこと」をチェックするだけなので、asyncTest()内でテストが完結している。必要であれば後続に処理結果チェック用のtest()を追加する。
3.3 テストコード作成時の注意事項
asyncTest()およびtest()外に記述されたコードは、start()を待たずに即実行される。
そのため、テストコードはasyncTest()およびtest()内に記述すること。
以上。
<関連エントリ>
QUnit+jQueryで、チンチロリンゲーム自動実行テストプログラムを作った
スポンサーサイト