テスト駆動ゲーム開発をJava scriptで実践
-
Upload
yuusuke-takeuchi -
Category
Documents
-
view
381 -
download
2
Transcript of テスト駆動ゲーム開発をJava scriptで実践
テスト駆動ゲーム開発をJavaScriptで実践
竹内 佑介
自己紹介竹内佑介です
仕事はバックエンド系ソフトの開発
趣味でnode.js+enchant.js
で通信対戦ゲーム
つくってます
テスト駆動開発とはプログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き(これをテストファーストと言う)、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイルである。
wikipediaより引用
http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA
要するに1. テストコードを書く
2. テストコードが動くプログラムを作る
3. プログラムのリファクタリング
を繰り返してプログラムを作る方法
ゲームのテストコードなんて書けるの
結論から言うと書きやすいところ、難しいところに分かれる
ざっくり言うと、フレーム処理、画面描画、コマンド入力がテストコード書きづらいです
上記処理のテストコードが書きづらい理由は次で簡単に説明します
フレーム処理が書きづらい理由ゲームの基本は無限ループ構造で、ループ毎の処理をフレームと呼ぶ
テストコードでは、XXフレーム後にテスト
コードへコールバック関数などで処理を返すという仕組みが必要
無限ループを外部から操作・参照したりすることを考えられるゲームライブラリは少ない
画面描画が書きづらい理由単純に画面描画結果に対して、アサーションを書くことが難しい
画像比較という方法もあるが、アニメーションが絡むとアホみたいな工数がかかる
ゲームの画面描画は頻繁に調整するところなので、上記方法はナンセンスすぎる
コマンド入力が書きづらい理由テストコードでどうやってジョイパッド入力、画面タッチを再現するのでしょうか
やってやれないこともないけど、
相当骨が折れそう
テストコード困難箇所まとめフレーム処理
➡テストコードからどうやってフレーム操作するの
画面描画
➡どうやってアサーションかけるの
コマンド入力
➡どうやってコマンド入力を再現するの
何とかならないでしょうか
苦肉の策でこうしましたゲーム画面には最低限の機能を実装 →大部分をテストコードが書きやすい作りにする
フレーム処理はenchant.jsのtimeLineオブジェクトを利用
コマンド入力はコマンド入力時のコールバック関数をテストコードで直接呼び出すことで解決
画面描画は……、やっぱり目で確認するしかないです
ゲームの作りゲーム画面は結果表示、コマンド入力だけをやっています
その他は全てサーバサイドに機能を持っています
システム構成
サーバ クライアント
ゲームロジック実行
コマンド入力コマンド送信
ゲーム結果送信 ゲーム結果表示
ゲームブラウザ
timeLineでフレーム処理元々timeLinemはアニメーション管理用機能
XXフレーム後にコールバックを実行という
形式で利用する
timeLineを応用して、指定フレーム後に
ボタン押下コールバック関数を呼び出す処理を書く
timeLineコード例//60フレーム後にGame.plusBattery()を呼び出すGame.battleScene.tl.delay(60).then(function() { Game.plusBattery();})//さらに20フレーム後にGame.selectBattery()を呼び出す.delay(20).then(function() { Game.selectBattery();});
※上記コードではボタン押下時コールバック関数Game.plusBattery()、Game.selectBattery() を直接呼び出している
timeLineは素晴らしいですフレームをまたぐ処理がスマートに書けてすごく便利です
DXライブラリではこういう書き方をしようと
思ったら、自作するしかないですね
これでイベント発火が出来れば最高なんだけどなあ
timeLineの詳細
timeLineについてのenchant.js公式ページ
http://wise9.github.io/enchant.js/doc/core/ja/symbols/enchant.Timeline.html
timeLine解説ページ
http://wise9.jp/archives/7418
ゲーム画面はどこまでテストコードでカバーできたのか
サーバ クライアント
コマンド入力コマンド送信
ゲーム結果送信 ゲーム結果表示
テストコード書けたテストコード書けなかった
テストコード書けない箇所のテスト実施方法
スタブを作成し、手動テストをやっています
ただ、スタブと自動テストのコードはほぼ同じです
timeLineを使ってボタン押下コールバックを呼
び出している箇所をコメントアウトしてるだけです
ぶっちゃけゲーム画面はテストコードよりも先に、スタブを作成しています
スタブが完成したら、それをテストコードに流用している流れです
スタブを手動テストと考えれば、一応テスト駆動と言えるはず……
他にも問題が・・・・・・アサーション内容がテストフレームワーク(mocha)上で表
示できません
mochaはテスト結果表示にhtmlを自動生成しまが、それが
enchant.jsのゲーム画面描画と競合します
しょうがないので、開発者コンソールにアサーションを表示しています
これは他のテストフレームワーク使えば解決できるかも…
ゲーム画面以外のテスト方法Webサーバ
selenium.jsでブラウザ自動テストを書く
ゲームロジック
普通にユニットテストを書く
socket.io テストコード内でサーバ、クライアントを生成して、クライアントはlocalhostに接続するようなユニットテストを書く
参考文献 http://dev.classmethod.jp/server-side/socket-io-client/
httpセッションとsocket.ioセッションの引き継ぎ
selenium.jsでブラウザ自動テストを書く
テスト駆動ゲーム開発をやってみて①
最初は開発速度が下がると感じましたが
しかし、コードが複雑になってくると、テスト駆動でやった方が断然早いと思いました
テスト駆動ゲーム開発をやってみて②
プロダクトコードはテストコードを書いてない頃よりも綺麗になりました
将来性を考えて汎用的に使える複雑なコードを書こう……、という考え方が減ったのが大
きいです
テスト駆動ゲーム開発をやってみて③
モジュール分けも綺麗にできるようになりました
テストコードを書かなかった頃は動いているコードを書き直すことに抵抗があり、モジュール分けも積極的に出来ませんでした
テスト駆動ゲーム開発をやってみて④
プロダクトの挙動が一目瞭然なので、新しい部分を作る時に参考になりました
テストコードを書かない頃は、ソースコードを全部読んでから新規コードを作成していました
テスト駆動で作ったゲームについて
ゲームのソースコードはここに公開
https://github.com/kaidouji85/gbraver
ゲームの説明はここ
http://www.slideshare.net/yuusuketakeuchi96/g-33989023
まとめ
javaScirptでテスト駆動ゲーム開発を実践した
timeLineを使えばフレーム処理がクールに書
ける
テスト開発駆動でもゲーム開発速度は落ちない
ご清聴ありがとうございました