バトルの自動テストツール

AvatarPosted by

この記事は GRIPHONE Advent Calendar 2019 9日目の記事です。

こんにちは。サーバーサイドエンジニアのtackです。

今回は、以前書いた記事(バトルのデバッグ効率アップツール)で紹介したツールを応用して開発した、スキル効果の自動テストツールを紹介します。

スキル効果テストツール

テストの実行、結果の確認、訂正を簡単に行う事ができるツールです。

テストの実行

全テストの実行、選択したテストのみ実行、失敗したテストの実行を行う事ができます。テストの結果は分かりやすく一覧で表示できるようにしています。テストの数はまだ少ないですが、40テストケースで 実行時間1分弱です。

テストの結果表示

今までPHPUnitでバトルのテストを書いていて、2番目に不便だったところはテストに失敗した際に、連想配列のアサーションを書いていると、どの値が間違っているのかがわかりにくく、原因を探すのに時間がかかってしまう事でした。
テストツールでは、スキル効果の実行ログの差分をわかりやすく表示しています。
以下の例だと、「Oblivion(忘却)の効果が発動するはずが、発動していない」ということがすぐにわかります。

テストケースの自動訂正

PHPUnitのバトルテストで1番不便だったのは、テストが失敗した際にそのテストを訂正することです。影響範囲の大きい修正だと、いくつもテストを訂正する必要がありかなり時間がかかります。しかも、スキルを発動するのに必要な多量のモックオブジェクトがあり、コードを読んで訂正するより書き直したほうが早い事もありました。そして、だんだんテストを書かなくなるという結果に・・・

そこで、テストツールにはテストに失敗した際に、現在の結果を正しい物としてテストケースを自動的に書き換える機能を実装しました。テストケース一覧にある「成功にする」ボタンをクリックするだけで、テスト結果が成功になるように書き換えられます。
何でもかんでも失敗したら、自動訂正ではテストの意味が無くなってしまいますが、テストが失敗したら、その結果を確認して正しい変更であれば自動訂正、間違っていたらコードを直して再実行というフローにして、今のところテストケースで網羅できている部分は上手くいっています。

テストケースファイル(JSON)

自動テストに使うテストケースを書いたJSONファイルは、以下の様な構造になっています。

  • テストケースの名前などの概要
  • RandomFixture
    バトルで使う乱数を固定するための情報
  • BattleFixture
    テストを実行するためのバトル情報
  • Assertions
    テストを実行するためのバトル情報

RandomFixture

バトルでは、効果の発動確率、ダメージ計算、ターゲットの選択などに乱数が使われています。自動テストを実行する際に、これらの乱数で結果が変わってしまうと、バトルが正しく動作しているかテストできません。
はじめは、乱数のシードを固定したらどうか?と思ったのですが、例えば「この効果は必ず発動させて、クリティカルにしたい」など、テスト時に扱いやすい値をシード値の固定だけで行うのは不可能でした。
そこで、乱数の値を呼び出し元毎に、任意の値に固定するようにしました。

{
    "Probability": 1.0,  //効果発動確率の値
    "Damage": 1.0,  //ダメージで使われる乱数の値
    "Attach": 1.0  //効果付着成功確率の値 
}

BattleFixture

テストを実行するバトルのカード、スキル、パラメータなどを再現させるための情報です。中身は以前書いた記事のバトルログシミュレータで使っているJSONとほぼ同じです。

Assertions

発動させるスキルと、そのスキルを発動させた後にバトルの状態がどのように変化するかの期待値を以下のように設定します。

  • スキル効果
  • 各キャラクターのパラメータ(HP、行動ゲージ量、攻撃力、防御力…)
  • 発動している状態異常効果

テストでは、この期待値と実際にスキルを発動させた結果値の差異を比較します。

おわりに

このスキル効果自動テストツールで、バトルのコードを変更する際に既存スキルへの影響範囲の確認や、デバッグに取られる時間と、バグがでないだろうか?という不安を減らす事ができました。

新しいスキルを実装する際や、バグ修正時に新しいテストケースを作る場合は、バトルログシミュレータを使い、実際のバトルからFixtureのJSONを作れるのでとても簡単です。
デバッグ担当の方に、スキルのデバッグをしてもらう時にJSONを記録しておいてもらって、それをテストケースにしておけば、次回からは同じデバッグは全自動で行えかなりの工数削減になりました。(「パッシブスキルを全部デバッグして!」と言って嫌な顔をされることも無くなりました)

今までやっていた結合テストでは、保守にかなりの時間を取られることもあり、だんだんテストを書かなくなってしまうこともありましたが、これなら続けられそうです。