はじめに
- 2018/06/06 (Wed) に開催された Unity テスト完全に理解した という勉強会に登壇したので、その感想を綴ります。
- また、内容に対する質問なども頂戴しているので、そちらに回答します。
「Unity テスト完全に理解した」とは?
- 私を含めた有志の Unity エンジニア数名が主催し、mixi さんに会場をお借りして開催された「Unity におけるソフトウェアテストについて語る勉強会」です。
- キッカケは @toru_inoue (a.k.a. 殺意開発駆動) さんに「こんな勉強会やりたいんだけど!」とご相談いただいたところからスタートしています。
- その後、イベント主催にめちゃくちゃ強い @lycoris102 (a.k.a. 青木とと) くんを巻き込み、会場提供いただいた mixi にお勤めの @adarapata(a.k.a. いも) さんも巻き込んで第1回の開催に漕ぎ着けました。
- タイトルが「つよめ」なのは、勢いで名前をつけたからに他なりませんw
セッション
スライド
ライブ放送アーカイブ
概要
- 「さては密結合だなオメー Clean Architecture で学ぶテストフレンドリーな疎結合設計」というタイトルで講演いたしました。
- 「如何にしてテストし易いコードベースにするのか?」というメタなテーマで、最近布教活動中な CAFU: Clean Architecture For Unity の宣伝を織り交ぜつつ、「こういう風にするとシステムが疎結合になって、テストし易くなるよ!」というお話をしました。
- 詳しくはスライドや録画放送をご覧くださいませ!
アンサー
- Twitter で講演中に頂戴したご意見やご質問に回答していきます。
- 基本的に時系列で回答していくので、読み辛いと思いますがご容赦ください。
Zenject 使わないとダメなの?
Zenjectでええんか...。逆にこれ使わないとUnityでテストできないということ?敗北感がある。#Unityテスト理解した
— 鉄 (@tetsujp84) 2018年6月6日
- スライドの中で @toRisouP さんの Unity開発で使える設計の話+Zenjectの紹介 というスライドについて言及した際の疑問かな?と思います。
- Zenject じゃなくても全く問題は無いのですが、Zenject able なシステムになっていると、テストが書きやすくなるのは事実なので、Zenject 使っているとテストが書きやすくなるというのは十分条件かな?と思います。
- @toRisouP さんも このツイート で触れていますね。
コードの数が多くなりそうなイメージある。
Clean Architecture数が多くなるイメージ#unityテスト理解した
— あるど (@OrangeGKeeper) 2018年6月6日
- はい。めっちゃ多くなります。
- 一つのシーンで20個くらい
.cs
ファイルが必要になるとかザラです。 - スライドの中で触れている CAFU: Clean Architecture For Unity では、コードジェネレータを実装しているので、作成時の手間はちょっと減らせているかな?とか思っています。
- 厳密に言うと CAFU Core 本体ではなく CAFU Generator という別モジュールで提供しているのですが、 README の Installation の作法に従ってインストールして頂ければ依存モジュールとして勝手にインストールされます。
この手のアーキテクチャの出自は?
ここらへんのアーキテクチャの話ってWebからの派生かな? #Unityテスト理解した
— 伊藤周@Unity退職→おなかソフト (@warapuri) 2018年6月6日
- 自分も詳しくは無いのですが、一説に依れば SI 系の出自という説もあり、はたまた Web という説もあり、イマイチ不明です…。
- なんとなくクライアントアプリケーション系な匂いもするのですが、どなたか詳しい方教えてくださいw
- @z_zabaglione さんが こちらのツイート で触れているように、OS のアーキテクチャとして考えるとシックリくるモノがあるので、そっち系の出自な可能性もありますね。
ちょっとしたアプリには向いてないのでは?
ちょこっとしたアプリを作るなら大げさすぎるかなぁって思っちゃうよね#unityテスト理解した
— たるこす (@tarukosu) 2018年6月6日
- はい。そう思います。
- 例えば 1Week GameJam などに出す単発アプリを作る場合などは、無理に使う必要性は無いと思っています。
- ローンチ後にも改良・改修を考えているプロダクトに適用すると良いんじゃないかなぁ?と思います。
何のゲームのオマージュ?
#Unityテスト理解した コラ○ス?w pic.twitter.com/JJJ4IwJn95
— ザバイオーネ@めぐるーま (@z_zabaglione) 2018年6月6日
- 「ぷ○ぷよ」です。
- 「テ○リス」とか「Fl○ppy Bird」とかも例示用に考えましたが、一番好きなゲームということで採用しました。
Mock じゃなくてよくね?
Mock いるか#Unityテスト理解した
— Z.Z.ずみっくす (@srz_zumix) 2018年6月6日
- はい。そう思います。
- ちょっと勢いで書いてしまった部分もあったので、わざわざ Mock しなくても良い箇所はあります。
どのレイヤーに当てはめるか?が難しい…。
ゲームは関心事多いからこんなに区分があっても全部適切に当てはまるか頭で理解が追いつかない #Unityテスト理解した
— そらむぎ (@soramugi) 2018年6月6日
レイヤーがいっぱいあると、何かコードを追加しようとしたとき「どこに書くべきか?」みたいなとこで時間かかるイメージあるんですけど、慣れれば早くなるとかですかね #Unityテスト理解した
— ウラコン@勇者、27歳、独身 (@uracon_) 2018年6月6日
レイヤーの選定で頭使いそうだなぁ(φωφ)
— IZUN∀@闇のXR狐 (@mizuki_izuna) 2018年6月6日
なれかな(φωφ)?
#Unityテスト理解した
- これはある程度の慣れが必要になるのは否めません。
- 実は、テストを書くようになるとスッと理解出来るようになったりします。
- 「ユーザ入出力に関するモノは View」「計算処理は UseCase」「データ入出力に関するモノは DataStore」と思っておくと良いかも知れません。
Translator, Repository, DataStore について
TranlatorとRepositoryは同じにしちゃっても良さそうな気はするかな?1回触ってみて様子見かな。
— とりすーぷ (@toRisouP) 2018年6月6日
#Unityテスト理解した
やっぱ、Translator、Repository、DataSourceあたりのレイヤー区分がこれで良いのかはちょっと気になるかなぁ。実際に触ってみて判断してみよう。
— とりすーぷ (@toRisouP) 2018年6月6日
#Unityテスト理解した
- Repository に Translator 的な処理を噛ませるのはアリだと思います。
- 私は、「Repository は単なるインタフェース」「Translator に変換の実ロジック」と分けたかったので、レイヤー分けしました。
- Translator には
Translate
メソッド一つのみを配置して、見通しを良くしたかったという思いもあります。
- Translator には
- その後のツイートで言及してくださっていますが、「DataStore が実ロジックで Repository はインタフェース」という理解で正しいです。
- 懇親会でもちょっとお話ししました。
RepositoryがDataStoreを使ってEntityを取り出し、Translatorを使ってModelに変換して返すって感じかな?Entityの裏にあるデータがJSONだとしたら1個のEntityに複数のModelが入ってる事はあり得るだろうか #Unityテスト理解した
— kanonji (@kanonji) 2018年6月6日
- その理解で良いと思います。
- 一つの大きい JSON をパースして、複数の Entity を含む大きい Entity のインスタンスを作る、という実装は結構やっています。
- ScriptableObject と可換にしようとするとかなり死ねるんですが、それは別のお話。
- Entity のリストを持つ Entity や、JSON のノードとして幾つかの種類の Entity を持つ Map (Dictionary) 的な Entity なんてのもバンバン使います。
Translatorは他のコンポーネントのように無理にクラス化しなくてもいいのではと思う。UniRx使ってるならデータなり何なりをレイヤの境界をまたいで伝搬させるときに、select等のオペレーターで変換するだけで十分なケースが多いと思う。 #unityテスト理解した
— d_yama (@dy_karous) 2018年6月6日
- これは、そうかも知れません。
- 私は、Entity や Model の構造を変更する時に UseCase を修正したくなかったので、Translator 層に退避させた感じです。
- 実際、CAFU を使ったとしても Translator 層ナシでも実装できます。
適用させやすいゲームとそうじゃないゲームがある?
アクション性の高いゲームは適用させにくい印象がある。一方RPGとかの静的ゲームには相性が良くて適用させやすい #Unityテスト理解した
— kamakama (@kama2vern) 2018年6月6日
- RPG などの方が適用させやすいのは事実です。
- というか、 適用させる価値が高い と言い換えられます。
- ですが、本質的にはどんなゲームにも適用できるかな?と思っています。
- アクションゲームで言うと、複雑なアクションの結果生じた「データの計算」やその「データの入出力」などの ルールを定義 しているに過ぎないため、見た目やアクションやエフェクトの複雑さとは切り離すコトが可能かなぁ?とは思っています。
- やったことないので何とも言えませんがw
もはや Unity 関係なくね?
ここまで来るとUnityからも疎結合にできそうね。別のフレームワークに差し替えとかもできてしまいそうだ。 #Unityテスト理解した
— とりすーぷ (@toRisouP) 2018年6月6日
- はい。その通りです。
- というか、そこを目指して開発しました。
- 元々普遍的な概念なので、「部分最適することで Unity に当てはめた」という感じですね。
Entity…?
DDDでいうEntityと意味が違うっぽくて混乱する #Unityテスト理解した
— kanonji (@kanonji) 2018年6月6日
- 懇親会でも何名かの方から聞かれたのですが、DDD の文脈に於ける Entity とは意味合いが違います。
- 元ネタのブログ では「An entity can be an object with methods, or it can be a set of data structures and functions.」とあるので、私は外部データ定義レイヤーとしてネーミングしました。
Repository と DataStore の分離
RepositoryとDataStoreの分離がどうなってるかが気になる #Unityテスト理解した
— kamakama (@kama2vern) 2018年6月6日
- 私は必要に応じて Repository レイヤーのサブクラス的な扱いで DataStoreResolver 的なモノを用意し、「利用する DataStore を選択するためのサブレイヤー」を追加定義することがあります。
- DataStoreResolver 自体も疎結合にする必要があるので、結構面倒ですがw
- この辺は、まだ画一的な方法が見出せておらず、プロジェクト毎に自由にやらせてしまっているのが実情です。
- 良案募集中です。
適用するの難しそう…。初速鈍そう…。
うっすらわかったけど、チームでやるときの初速難しそう
— あるど (@OrangeGKeeper) 2018年6月6日
でも、試してみたい#unityテスト理解した
Clean Architecture 初手でゲームに適用してやるとわけわからんってなる未来が見えるのでまずエディタ拡張あたりで落ち着いて書いてみるのがいい気がする #Unityテスト理解した
— かまたけんし (@knsh14) 2018年6月6日
テストフレンドリーなアーキテクチャであればあるほど開発スピードが犠牲になりそうなイメージ #Unityテスト理解した
— りょポン.saito (@Lynx_ryopon) 2018年6月6日
- はい。容易ではありません。
- 正直、初速は良くありません。
- が、慣れると、めちゃめちゃ速いです。
- 1本小さめのアプリ書き上げるくらいまで使うと、その後の開発は相当楽になります。
- 元々弊社プロダクトは、小さめのアプリを大量に作って一つのアプリにする必要があるという特性があるので、その辺をかなり意識して作りました。
もんりぃ先生と一緒に導入しないと難しそうだw #Unityテスト理解した
— 立福 寛 (@TATEXH) 2018年6月6日
クリーンアーキテクチャ師範みたいな人が最初にいて、そこに皆集まってくる感じのチームだとめっちゃ強そう #Unityテスト理解した
— ウラコン@勇者、27歳、独身 (@uracon_) 2018年6月6日
- コンサルティングもやぶさかではありませんよ?w
密結合なアセットどーすんの?
これ、蜜結合な外部アセットを導入するとかどんな感じで運用するんだろう。
— えむにわ@アツクテシヌゼー (@m2wasabi) 2018年6月6日
汚れる~とか言いながら我慢するのかな
#Unityテスト理解した
- 私はロジックにガッツリ介入してくるようなアセットは殆ど使っていません。
- Unity の文脈で言うところの Component に該当するアセット(View レイヤー)はバンバン使っちゃって良いと思いますが、 View 以降のレイヤーに介入してくるアセットは、相当厳選して入れています。
コードジェネレータないの?
エディター拡張で各レイヤーとかのテンプレ生成とかできると良いのかな#unityテスト理解した
— あるど (@OrangeGKeeper) 2018年6月6日
CAFU のテストなくね?
CAFU 自体のテストがない#Unityテスト理解した
— Z.Z.ずみっくす (@srz_zumix) 2018年6月6日
- はい。書きます。
- ドキュメントやサンプルとともに喫緊の課題として積んでおります…orz
所感
- mixi さんのイベントスペースがとても良く、感動しきりでした。
- 最大90名程度の収容力
- 2面スクリーン
- ワイヤレス映像出力
- 生放送・録画機材
- おしゃれ感
- etc...
- イベント自体は、公開直後に満席になり、増席してもなお人が増え続けて、ピーク時には定員90名のところに158名もの方にご応募いただくという、「このテストケースは書けなかったわーw」という状況にまでなりました。
- 流石に90人(スタッフ入れたら100人超えていたかも?)の前でフルセッション話すのは(多分)はじめてだったので、登壇直前までガッチガチに緊張していましたが、会場の空気が精神的な意味で暖かく、落ち着いて話すことができました。
- スライドが100Pを超えていたので、早口にはなっていたと思いますがw
- 結果、ほとんど無言ドタキャンもなく、セッションは勿論のこと懇親会も大いに盛り上がり、「大成功」と言える勉強会になったと思います!
- メインで動いてくれた青木ととくんや登壇者の皆さんや現場で設営・撤営・録画など多大なご協力をいただいた mixi 社の方々に、この場を借りて改めて深く御礼申し上げます!ありがとうございました!!!