この記事は KLab Advent Calendar 2018 14日目の記事です。
こんにちはhamasan05です。
先日CEDEC+KYUSHU2018に
大規模モバイルオンラインゲームを支えるソフトウェアアーキテクチャ開発とその使用例
というタイトルで登壇してきました。
(資料はただ今公開準備中なので公開次第URL差し替えます)
セッションを準備するにあたってたくさん準備をしたのですが
泣く泣くカットしたことがたくさんありました。
今回はその中で有用なプログラムネタがあったので紹介します。
「自動テストの拡大」に関する部分です。
セッションの概要
新しいアーキテクチャの採用によりサーバクライアント間のテストを自動化することに成功したのがセッションでのお話
実際にどうやっているのか
今回紹介する内容ではクライアント側はUnity(言語はC#)、サーバ側はPythonを利用しています。
ドライバはPytestを利用していて通信の置き換えはPython for .NETを利用しています。
Python for .NETの使い方についてはすでに記事があるため割愛します。
今回は実際にテストに利用する際に気をつけるべき点として
3つのポイントを紹介させていただきます。
- クライアントロジックはピュアなC#で記述する
- サーバロジックの時間のかかる処理はまとめてパッチを当てておく
- クライアントロジックとサーバロジックを通したテストは一番最後にやる
クライアントロジックはピュアなC#で記述する
ロジック部分はピュアなC#で記述してmonoでコンパイル可能かつ動作できるようにしておきます。
これはテストがどんな環境でも動くようにするためです。
UnityEngineに依存した部分やOSに依存した部分があると動作する環境が限られてしまいます。
(作業者のPCなどでは動くが、サーバではUnityやAndroid SDK、Xcodeなどインストールしないと動かない等)
環境を選ばずにテストできることによって、テスト用に高速なマシンを選択したり、並列処理をしたりと柔軟性が拡大します。
上記の観点からクライアントロジックの一部はテスト用に差し替えられるように設計上隔離しておくと良いです。
UnityEnginge等に依存する処理は隔離した上でテストに影響を与えない処理に差し替えたダミーを準備しておきます。
また、通信を行う処理についても物理的に隔離しておく必要があります。
こちらは単純なダミーではなくPython側の処理をコールする処理で上書きをしておきます。
これらのダミーのクラス群とプロダクトに含まれるべきロジック部分をコンパイルしてDLLを作成してテストを行います。
サーバロジックの時間のかかる処理はまとめてパッチを当てておく
テストで大幅に時間がかかる箇所については、Pytestの共通の初期処理で予めパッチを当てておきます。
大幅に時間が掛かるものの代表例としてはネットワーク関連になります。
DBや他のサービスへのアクセスが有る場合はサーバ側でも共通で固定値を返すようなダミーを作って
パッチを当てておくと良いです。
クライアントロジックとサーバロジックを通したテストは一番最後にやる
当たり前の話ではあるのですがC#とPythonのテストをそれぞれきっちりやってから最後に通しのテストをしたほうが良いです。
このテストは一定成約があり問題があったときに原因特定がやや難しいです。
デバッガが使えなかったりスタックトレースが情報不足だったりします。
(問題があった場合はデバッグライトを使って駆使して特定しているのが現状です)
できるだけ品質を上げた状態でテストすることが望ましいです。
最後に
CEDEC+KYUSHU2018での私達のセッションに参加していただいた皆様、この記事を読んでくれた皆様に心より感謝します。