ページ 11

テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 10:53
by newpro
現在C++/DxLibでゲームを作成中なのですが、テストコードをどこまで書くべきか、ということで悩んでいます。
最近ではTDDでまず最優先でテストコードを書け、と言われますが、ゲームプログラムは引数も戻り値もvoidの
画面処理のみを行うコードが多く存在します。
無理して書くものでもないとは思うのですが、結果は目視で確認するしかないものであっても(それこそカバレッジを通すために)
テストコードを書くべきなのでしょうか。
(必要箇所のみ書く方針でいると、ほとんどテストコードの存在しない結果となりそうです)

また、Visual StudioのExpress版でも2012からはMSTestに対応しているということで、今回これを使用したいと考えています。
ただ分かりやすい解説のサイトをあまり見つけられていないため、もしお勧めのサイトがあれば教えて頂きたいと思います。
(NUnitのほうが良いのでしょうか。そもそも個人で作成するプログラムでは一般的にテストを記述するものなのでしょうか)

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 14:48
by h2so5
ゲームプログラムでテストを書くのは難しいので無理に書く必要はないと思います。
特に描画処理はライブラリ自体のテストはともかく、アプリケーション側では人間が判断するしかありません。

書けるとすればロジックの部分ですが、これはゲームのジャンルによって大きく左右されると思います。
カバレッジを通すために無意味なテストコードを書くのは本末転倒です。

個人で開発しているプログラムでもライブラリなどについては僕はテストコードを書いています。

C++用のMSTestの解説
http://whinery.wordpress.com/2012/07/21 ... h-ms-test/

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 16:48
by softya(ソフト屋)
ゲームプログラム自体は条件が多すぎる & 状態が多様である と言う理由からテストコードによるテストは困難です。
※ 将棋など、条件が特定できるボードゲームを除きます。
セーブ・ロードや計算周りなど、部分的にテストコードによるテストも可能なところで使うべきかと思います。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 19:36
by たいちう
ゲーム作成経験の無い人の便乗質問なのですが、、、

> ゲームプログラム自体は条件が多すぎる & 状態が多様である と言う理由からテストコードによるテストは困難です。

「入出力に密接に関わる部分が大半なので、」とかいう理由ならば想像できるのですが、
この理由については疑問を感じます。

「条件が多すぎる & 状態が多様である」というのは、他のシステムと比較して本当でしょうか?
また、私の経験では「条件が多すぎる & 状態が多様である」場合ほど、テストコードがありがたいです。
もしよろしければ、ご説明頂けないでしょうか。

# 私はテストコードを書きたいけど書けない場合が非常に多いため苦労しています。
# もし変な勘違いや食わず嫌いでテストを書いていないならばもったいないなという思いと、
# 他の業種の事情が何らかのヒントになればラッキーという思いからの質問です。
#
# 無理してでも書くべき、という意見ではないですよ。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 20:48
by softya(ソフト屋)
特定の状況に追い込んでのテストは可能ですが、ランダム順序を制御したり、特定のステータスを設定しないと出来ないことが多すぎて実際のプレイと異なってしまうのが問題です。
あとマップ上のテストは、地形を網羅して歩く・走るというのは自動テストでは困難です。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 21:59
by ISLe
ゲームプログラムはシンプルな機能の複雑な組み合わせが延々と繰り返され状況が変化することで動くものです。

例えばイベント入れ忘れても、いきなりラスボス倒せるキャラを作れても、自動テストで誤りと判定することはできません。
特定のマップで壁にハマらないかどうかなどを検出するためには天文学的な数のマップが必要で、自動生成するにしても自分が生きているうちにテストが終わるかどうか分かりません。

というわけで、完成品(に近いもの)で実際にプレイしながらデバッグするというのがもっとも効率が良いということになるわけです。


シンプルな機能の組み合わせで作れないひとを、そうなるよう仕向けるためにTDDを活用するというのはアリだと思います。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 23:45
by たいちう
softyaさん、ISLeさん。

回答ありがとうございます。
(私と比べたら)概ねお二人の立場とご意見は近いものと考え、まとめて返信させていただきます。


(softyaさん)
> 特定の状況に追い込んでのテストは可能ですが、ランダム順序を制御したり、
> 特定のステータスを設定しないと出来ないことが多すぎて実際のプレイと異なってしまうのが問題です。

(ISLeさん)
> ゲームプログラムはシンプルな機能の複雑な組み合わせが延々と繰り返され状況が変化することで動くものです。

↑の事は、ゲームプログラム特有の話ではないと思うのですが。
例えば、MS-Word。例えば、基幹システム。
このようなプログラムについても同じことが言えるのではないでしょうか。
特定の状況を再現させるために苦労することも同じです。


(ISLeさん)
> 例えばイベント入れ忘れても、いきなりラスボス倒せるキャラを作れても、自動テストで誤りと判定することはできません。

↑Event管理クラスやキャラクタ作成クラスがあったとして、必要なテストを追加すれば良いのではないですか?
テストを追加しないといけないのは、他の業種でも同じです。


(softyaさん)
> あとマップ上のテストは、地形を網羅して歩く・走るというのは自動テストでは困難です。

(ISLeさん)
> 特定のマップで壁にハマらないかどうかなどを検出するためには天文学的な数のマップが必要で、

↑については、残念ながら私には想像ができません。きっとテスターの経験でカバーできるのでしょうか。
その場合でもテスターが発見したバグを分析し、そのエッセンスをテストコードにできれば、
今後、同じ原因の不具合が発生しないことを保証できる強みがあると思うのですが。素人考えなのでしょうね。


(ISLeさん)
> というわけで、完成品(に近いもの)で実際にプレイしながらデバッグするというのがもっとも効率が良いということになるわけです。

↑という結論に多くのゲームプログラマの皆さんが達しているのでしょうから、
それが今日のゲームプログラミングでの正解(多数派?主流?最適解?)なのだと信じます。



私自身TDDのあり方について、多くの形態・言語のシステムで何年も試行錯誤を続けていますので、
ゲームプログラマが何故興味を持たないのか、明確な理由が聞ければいいなと思ったのですが、
理解できませんでした。折角回答頂いたのに申し訳ありません。

ともあれ便乗質問へのご回答ありがとうございました。
それとnewproさん、お邪魔しました。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月23日(土) 23:53
by softya(ソフト屋)
テスターが行う、やばそうな地形の隙間に突進ってのはパターン認識に属するので、どちらかと言うと人工知能の分野かと思います。
人工知能をテストに応用するのは、まだこれからって気がしますよ。
アメリカのシステム化されたゲームのテストでも、テスト会社が人間のゲーマーを雇っているので自動化が困難なのだと思います。

【補足】イベントのバグも同様でしょうかね。

【補足の補足】
>特定の状況を再現させるために苦労することも同じです。

これは自動テストでは出ない系統のバグではないでしょうか?
基幹システムでもwordでも。

【補足の補足2】
ゲーム系でもライブラリのテストやアイテムなどの組み合わせ網羅テストなどでは自動化は行われています。
ただ本編は仕様がころころ変わることが多すぎて、テストコード自体がすぐや立たずになるので嫌われているのかな?と言う気はします。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月24日(日) 00:56
by たいちう
> テスターが行う、やばそうな地形の隙間に突進ってのはパターン認識に属するので、
> どちらかと言うと人工知能の分野かと思います。
> 人工知能をテストに応用するのは、まだこれからって気がしますよ。

そうではなくて、テスターが発見したパターンをテストコードとして追加するのです。
その後も、仕様変更や別のバグの修正、もしかしたら移植した際に、
同じ原因の不具合がないことを保証しようというものです。

「Aというバグを直して、数週間後にBを別の人が直したら、気付かぬうちにAが再発していた」という、
モグラたたきみたいな状況に陥ったことはないですか?


> 【補足の補足】
> >特定の状況を再現させるために苦労することも同じです。
>
> これは自動テストでは出ない系統のバグではないでしょうか?
> 基幹システムでもwordでも。

特定のコード(例外処理等)をテストするために苦労する、という意味で書きました。
適切な設計とテストがあれば、自動テストで検出可能な系統のバグの話をしています。
(実際には殆どの場合、不適切な設計と不完全なテストなので検出は不可能かもしれませんが)


> ただ本編は仕様がころころ変わることが多すぎて、テストコード自体がすぐや立たずになるので嫌われているのかな?と言う気はします。

仕様が変わるのは基幹システムでも同じことで、当然テストコードも変更が必要になります。
こちらでも朝令暮改は珍しいことではないですが、それでも変わる頻度はゲーム作成の方が桁違いに多いかもしれませんね。

ですが、仕様が頻繁に変わる場合こそ、自動化テストが重宝されるべきです。
仕様が頻繁に変わる場合に、テストまでメンテしなくてはならない、というのは確かに嫌われますね。
正直なところ、テストがあればうれしいけど、自分がテストを書く労力は割けないとかいう意見も。

Re: テストコードの記述について(C++/DxLib)

Posted: 2013年11月24日(日) 01:06
by ISLe
たいちう さんが書きました:例えば、MS-Word。例えば、基幹システム。
このようなプログラムについても同じことが言えるのではないでしょうか。
特定の状況を再現させるために苦労することも同じです。
例えばMS-Wordは1ページ目に入力した内容によって、同じ操作で2ページ目に入力した内容が変化するでしょうか。
基幹システムでキーボードから入力するタイミングやマウスをクリックするタイミングで金額が増えたり減ったりするでしょうか。
ゲームは同じ操作の繰り返しでもどんどん状況が変わります。
そのような部分にテスト項目を用意することは事実上不可能です。

他の方が既に書かれていることの繰り返しになりますが、特定の入力に対して特定の出力が行われるモジュールにおいては単体でテストします。
ゲームプログラムを単なるコードの羅列としてみれば、制御部分のほとんどが単体でテストされていると考えて良いと思います。
しかしそれでゲームが正しく動くようにはなりません。
プログラムが正しく動くかどうかとゲームとして正しく動くかどうかは別の問題で、ゲームを正しく動かす中でプログラムが持つ役割の大きさは(個人的な見解ですが)ほんのわずかだと思います。