正常系テストと異常系テスト、大変なのはどっち?【ゲーム開発】
プログラミングの後にはテストを行うフェーズがセットでついてきます。むしろテストこそプログラミングの真髄なのではと思うくらいには時間を費やすことになる部分です。
「思った通りに動かない……」という悩みに対しては「プログラムは思った通りには動かない、書いた通りに動くのだ」という正論をぶつけられることもしばしば。人間が書いたコードというのは思い描いたことを100%盛り込めていることなんて少なくて、多くの場合意図を正しく反映できていない状態で生み出されます。
こうして生み出されたコードに対してテストを行うことによって思い描いた姿に近づけているんですね。思い描いた姿を実現できているか、という点はゲームを作っていて非常に意識の向く部分ですが、自分が意図していない動作の確認についてはうっかりすると忘れてしまうこともあるかもしれないので、胸に留めておくとグッド。
思い描いた通りの動きを確認するのは正常系テスト、意図しない動作の確認をするのは異常系テストと呼ばれます。論調で「どちらが大変か?」という点はバレていそうな気もしますが、このページでは正常系テストと異常系テストのどちらが大変かを個人的な観点から述べています。
正常系テストと異常系テスト、大変なのはどっち?
この話題を出しておいてアレですが、正常系、異常系という分け方は人によって異なったりします。あくまでここでの分け方ですが、ゲームだと製作者側が通常プレイとして考えている範囲のテストを正常系テスト、通常プレイではなく起こって欲しくないプレイの範囲のテストを異常系テストと分けます。
例えばパズルゲームで1回のゲームを通常通りプレイする流れを確かめるのは正常系のテストです。想定通りに遊べることを確認していく作業になるので、分かりやすい部分ですね。ゲームオーバーの処理なども通常プレイの範囲内だと思っているので、正しくゲームオーバー時の処理ができていることも確認します。
異常な動作というと、例えばパズルのピースをタップするようなゲームであれば、ピースを同時にタップした時におかしな動きをしないかどうかを確かめます。また、ポーズボタンを押すタイミングで何度も連打してみて、メニュー画面がいくつも表示されたりすることがないかを確認します。
実は以前別のページでも似たようなことをお伝えしていました。これは異常系のテストをしようという部分をもう少し噛み砕いてまとめてみたものです。
近年のゲームではネットワークを使う機会も増えています。広告を表示するなら広告データのやりとりでネットワークを使いますし、ランキング機能があるならランキング登録の際にネットワークを使います。もしかしたら同時対戦の機能も実装しているかもしれませんね。
こうした時に、通常プレイではネットワークがきちんと繋がっている想定で動きますが、もし通信中にネットワークが途切れたらどうなるでしょうか? もしかしたら真っ暗な画面でずっと「接続中……」のアイコンが表示されているかもしれません。
プレイヤーが行う操作だけではなく、環境面でも異常が発生した時の動作を確認しておく必要があります。
操作は分かりやすいけど環境系は大変
意図的に変な操作をしてみるのは比較的分かりやすい部分かと思います。なぜなら開発者側が能動的に操作できる部分ですからね。
環境系の異常を確かめるのはなかなか骨が折れます。例えばランキング機能だと、送信処理中にネットワークが切れた時、サーバから結果を受け取る途中でネットワークが切れた時、といった感じでフェーズごとに確認していく必要があります。
また、サーバ側でエラーが発生したケースも確認しておいた方がいいかもしれません。異常な値が渡された時に正しくエラーを返せるかどうかは大切です。通信用のパケットを偽装してランキング1位相当のスコアが送信されちゃうかもしれませんからね。個人でやっているゲームならチート対策は万全にやろうとすると工数がとんでもないことになりますが、ソシャゲ系ならやっておかないと普通に遊んでくれているユーザが不満を持ってしまいますからね。
他にも何かの処理を行っている時にゲーム機の電源を落としたり、アプリを強制終了させたりして動作を確認するのも大切です。異常なデータが書き込まれないかも確認しておくといいですね。例えば昔小中学生の頃に流行ったポケモンの裏技に「レポートを書いている途中で電源を切るとボックスに預けたポケモンが増殖する」みたいな裏技がありました。ポケモンに道具を持たせておくとそれが増殖するのでマスターボールをたくさん手に入れたりしている友達もいました。
データを書き込んでいる途中で処理を終了した場合、ストレージに書き込んだデータがどうなるかも要チェックです。
……なんて感じで「こんな操作普通しないでしょ!」という部分を確かめるのが異常系テストです。
異常な動作の後の対応
異常な動作を試してみたら、案の定よく分からないエラーを吐くことは多々あります。こうしたエラーをうまくハンドリング(対処)していくことが大切です。
エラーのハンドリングについては以下のページでも触れています。
例えばボタンを連打したらメニュー画面が10個くらい開いた! なんて時にはボタンを押した時の制御を入れておきましょう。ボタンのinteractableをfalseにして押せないようにしたり、メニュー画面の背景パネルでRaycastTargetを設定したりする方法があります。これはユーザに見せるまでもなく開発中に直せてしまいます。
あるいはInputフィールドでは入力値の検証も必要ですね。正常な値と異常な値をテストケースとして準備して、それぞれ入力した時の処理を制御しておきましょう。例えばお店でアイテムの購入数を入力できる場合は、数字以外が入力された時にはどうなるか確認する必要があります。……この場合は数字以外を入力できないようにした方がいいですね(笑)
ネットワーク接続でエラーが発生する場合は、タイムアウトの処理を入れたり、エラーコードを画面に表示して「リトライ」または「タイトルに戻る」ボタンを表示する方法があるかもしれません。ネットワークの異常についてはユーザが意識してないことが多いので、延々と待たせてしまうのは不安を煽ってしまいます。
うまく行っていない状況をユーザまたは開発者に知らせるための手立てを画面で表示するようにしましょう。開発者側でネットワークの切断を防ぐ手立てはないので、発生してしまうことは前提として、発生した時に対処できるようにしておくとグッド。
開発者側で潰せるエラーはなくしておいて、ユーザ側で発生する可能性があるエラーについてはなるべくゲームの動きの中で正常な流れに戻せると良い感じです。
まとめ
正常系のテストと異常系のテスト、どちらが大変かというと個人的には異常系のテストが大変だと思います。その状況を発生させるのが大変なので試行回数もなかなか重ねられなくて時間がかかることもあります。「こういうケースは大丈夫かな?」と異常な動作を想像するのもなかなか頭を使う部分です。
さりとてやらない訳にはいかないので、安定したゲームにするために異常系のテストもやる! という点を意識しておくとグッド。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】AndroidSDK、UnityのものとAndroid Studioのもの、どっち使う? 2020.12.22
-
次の記事
【Unity】AndroidのAPIレベルとOS、SDKとの関係を整理してみる 2020.12.24
コメントを書く