Unityで開発しているゲームの単体テストをCI環境で運用している話

こんにちは。Quality Assurance部で新規開発プロダクトの品質保証を担当しております@haruna_nishiです。このエントリーは「GREE Advent Calendar 2015」21日目の記事です。

昨年も21日目に「開発チームから激モテ!ネイティブゲーム時代の愛されQA」というタイトルでアドベントカレンダーを書かせていただいたのですが、今年は私が開発チームの中で実際にどのようなことを行っているのか具体例を挙げて紹介致します。

新規プロダクト開発におけるテストエンジニアリングの取り組み

本題に入る前に、今一度Quality Assurance部としてのテストエンジニアリングに対する取り組みを紹介させてください。

Quality Assurance部の中でも、Product Operationグループ(Webゲーム、新規事業を軸に品質保証を担当しているグループ)としての技術的な取り組みは、7日目にやまもとさんが書かれた「グリーのテストエンジニアとテスト戦略」に記載されています。

対してNew Productグループとしてのテストエンジニアリングに関する取り組みは以下の二種類の方向性があり、

  • 特定の開発チームに特化した支援を行う
  • 特定の開発チームに依存しない共通の課題を解決するために支援を行う

@ma3tkさんが8日目に書かれている「OpenSTFの導入によるゲーム開発への貢献」は、後者にあたります。

今回私がご紹介する具体例は前者にあたりますが、どちらの取り組みにおいても、「プロダクトの生産性と品質向上に対し、技術面から支える」というミッションを達成するべく日々働いています。

弊社では慣習上、Product Operationグループのエンジニアを「テストエンジニア」、New Productグループのエンジニアを「QAエンジニア」として呼び分けていますが、志は同じく品質向上に貢献することです。

Unityの単体テスト実行とチームでの運用

私は新規プロダクトの開発チームの一員として、テスト計画を作成したり、単体テストを日々実施できるCI環境を整えたりしていますが、その中でも今回はUnityの単体テストのCI環境を構築して運用している事例についてお話したいと思います。

単体テストの実行環境について

まずはじめに、利用している単体テストの実行環境をご紹介します。

Unityで単体テストを書く場合、一般的には「Unity Test Tools」の「Unit Tests Runner」を利用することが多いかと思います。※注1

Unity Test Tools

Unity Test ToolsはAsset Storeから無料でダウンロードができます

「Unity Test Tools」はエディタ上での操作も直感的で導入しやすく、NUnitが使われているため、NUnitを使った事がある方は容易に書く事ができるかと思います。また、結合テストを行う事もでき、実機上で結合テストを実行させることも可能です。

これから新しくテストを書く場合、一般的にはUnity Test Toolsを利用するのが良いと思うのですが、私が担当している開発チームでは、OSSである「UniUnitTest」を利用して単体テストが書かれています。

UniUnitTest実行時スクリーンショット

UniUnitTest実行時のスクリーンショット:シーン再生をすることでテストが実行できます

Unity Test Toolsと比較した場合のUniUnitTestの利点は以下の通りです。

  • 単体テストも実機上で実行できる
  • 実行時と同じコードで単体テストを行える

私が担当しているチームはUnityのAssetBundleを利用して開発しているのですが、アセットが該当プラットフォーム上でコードとの互換性を保てているか(アセットが参照しているコードに変更がないかどうか)を確認するには該当プラットフォーム上で動かすことが必要です。どのアセットの互換性がなくなっているのかを検証するような場合などに実機上で単体テストを実行したいため、UniUnitTestを利用してテストを行っています。

構築したCI環境について

次に、私が担当プロダクトで構築したCI環境についてご紹介します。

弊社では、全社的に利用しているCI環境がJenkinsを用いて作られているため、チームにもJenkinsを導入しました。

UniUnitTestはUnityのバッチモードで実行できるため、特殊なことを行わずにテスト実行を自動化することができ、実行の自動化は特に問題なくスムーズに行えました。

単体テストやアプリ・アセットのビルドにはUnityがインストールされていることが必要で、またiOS用のアプリをビルドするにはXcodeが必要なため、JenkinsマシンはMacPro一台をマスター、MacbookPro一台をスレーブとして利用しています。

jenkinsマシン

チームのjenkinsマシンはこのような形で執務室内で働いています

構築後に見えてきたUnityの単体テストを運用する上での課題

先述の通り、単体テストの自動実行環境は構築できたものの、実際に運用すると「テスト時間が長いためテストの待ち行列ができてしまう」という課題にぶつかりました。

私が担当しているチームは、プルリクエストごとに単体テストを自動実行し、レビューしてもらった上で単体テストが成功したらマージするルールになっています。

プルリクエストマージフロー

プルリクエストのマージフロー図※チームごとにルールは違います

職種に関わらずファイルやコードの変更はリポジトリにプルリクエストを出して取り込んでもらうことにしているため、多いときは一日で10個以上のプルリクエストが出され、その度にテストが実行されるため、出したプルリクエストのテストが終わるまでに何時間も待つということがざらにありました。

テスト時間が長くなっていた要因は複数あったのですが、主なものは以下の通りでした。

  • Libraryフォルダを削除していたため、アセットのインポートに時間がかかっていた
  • AssetBundleのビルドに時間がかかっていた
  • 全アセットをロードして参照をチェックするテストに時間がかかっていた

また、プルリクエストによっては必要のないテストも毎回全て実行していることもテストの実行時間が長くなっていた原因でした。

負荷分散をしようにも、Unityが動くマシンの手配が思うようにできなかった事情もあり、以下のように運用を変更しました。

  • Libraryフォルダは必要な時以外は削除しない
  • 各プルリクエストの内容に必要なテストだけ行なう
    • アセットに対するテストは、アセットに変更があった時だけ行なうなど
  • プルリクエスト時とは別に定期的に全てのテストを行なう

このような運用に変更した事で、テストの実行時間を削減することができ、ゲームを開発する上でのボトルネックを緩和することができました。

今後の取り組み

現在、テストに関しては単体テストをUnity上でのみ自動化を行っていますが、社内にSTF(Smartphone Test Farm)も構築されたので、今後はSTFに接続された端末上での単体テスト自動化などにも取り組みたいと考えています。

モバイルゲームは、Webアプリやネイティブアプリのように規定のUIコンポーネントを利用して開発しているわけではないため、実機上でのテストを自動化するのが難しい分野ですが、難しいからこそやりがいや面白さがある分野です。

最後に宣伝

今年の夏、Webサービスやモバイルアプリ・ゲームなどの品質保証に携わる女性達が情報交換をしたり飲んだくれる場である「QA女子会」を結成しました。主な活動はSNS上での情報共有・意見交換で、時々実際に女子会を開催することもあります。テストに興味のあるそこの貴女、仕事で直接品質保証に携わっていなくても構いませんので是非気軽にご参加ください!

明日は瀬島さんによる「InnoDBのmutexの話(入門編)」です。お楽しみに!

 


※注1 Unity5.3で、Unity Test Toolsの単体テスト部分はEditor Tests Runnerに移行されました。以前は単体テストを[Unity Test Tools] > [Unit Test Runner]で実行できましたが、Unity5.3からは[Window] > [Editor Tests Runnner]でテストランナーウィンドウが開くように変更されました。