もんりぃ is undefined.

育児ネタとか、技術ネタとか。

「Unity テスト完全に理解した #1」に登壇しました

はじめに

  • 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

セッション

スライド

speakerdeck.com

ライブ放送アーカイブ

www.youtube.com

概要

  • 「さては密結合だなオメー Clean Architecture で学ぶテストフレンドリーな疎結合設計」というタイトルで講演いたしました。
  • 「如何にしてテストし易いコードベースにするのか?」というメタなテーマで、最近布教活動中な CAFU: Clean Architecture For Unity の宣伝を織り交ぜつつ、「こういう風にするとシステムが疎結合になって、テストし易くなるよ!」というお話をしました。
    • 詳しくはスライドや録画放送をご覧くださいませ!

アンサー

  • Twitter で講演中に頂戴したご意見やご質問に回答していきます。
  • 基本的に時系列で回答していくので、読み辛いと思いますがご容赦ください。

Zenject 使わないとダメなの?

  • スライドの中で @toRisouP さんの Unity開発で使える設計の話+Zenjectの紹介 というスライドについて言及した際の疑問かな?と思います。
  • Zenject じゃなくても全く問題は無いのですが、Zenject able なシステムになっていると、テストが書きやすくなるのは事実なので、Zenject 使っているとテストが書きやすくなるというのは十分条件かな?と思います。
  • @toRisouP さんも このツイート で触れていますね。

コードの数が多くなりそうなイメージある。

  • はい。めっちゃ多くなります。
  • 一つのシーンで20個くらい .cs ファイルが必要になるとかザラです。
  • スライドの中で触れている CAFU: Clean Architecture For Unity では、コードジェネレータを実装しているので、作成時の手間はちょっと減らせているかな?とか思っています。
    • 厳密に言うと CAFU Core 本体ではなく CAFU Generator という別モジュールで提供しているのですが、 README の Installation の作法に従ってインストールして頂ければ依存モジュールとして勝手にインストールされます。

この手のアーキテクチャの出自は?

  • 自分も詳しくは無いのですが、一説に依れば SI 系の出自という説もあり、はたまた Web という説もあり、イマイチ不明です…。
  • なんとなくクライアントアプリケーション系な匂いもするのですが、どなたか詳しい方教えてくださいw
  • @z_zabaglione さんが こちらのツイート で触れているように、OS のアーキテクチャとして考えるとシックリくるモノがあるので、そっち系の出自な可能性もありますね。

ちょっとしたアプリには向いてないのでは?

  • はい。そう思います。
  • 例えば 1Week GameJam などに出す単発アプリを作る場合などは、無理に使う必要性は無いと思っています。
  • ローンチ後にも改良・改修を考えているプロダクトに適用すると良いんじゃないかなぁ?と思います。

何のゲームのオマージュ?

  • 「ぷ○ぷよ」です。
  • 「テ○リス」とか「Fl○ppy Bird」とかも例示用に考えましたが、一番好きなゲームということで採用しました。

Mock じゃなくてよくね?

  • はい。そう思います。
  • ちょっと勢いで書いてしまった部分もあったので、わざわざ Mock しなくても良い箇所はあります。

どのレイヤーに当てはめるか?が難しい…。

  • これはある程度の慣れが必要になるのは否めません。
  • 実は、テストを書くようになるとスッと理解出来るようになったりします。
  • 「ユーザ入出力に関するモノは View」「計算処理は UseCase」「データ入出力に関するモノは DataStore」と思っておくと良いかも知れません。

Translator, Repository, DataStore について

  • Repository に Translator 的な処理を噛ませるのはアリだと思います。
  • 私は、「Repository は単なるインタフェース」「Translator に変換の実ロジック」と分けたかったので、レイヤー分けしました。
    • Translator には Translate メソッド一つのみを配置して、見通しを良くしたかったという思いもあります。
  • その後のツイートで言及してくださっていますが、「DataStore が実ロジックで Repository はインタフェース」という理解で正しいです。
  • 懇親会でもちょっとお話ししました。

  • その理解で良いと思います。
  • 一つの大きい JSON をパースして、複数の Entity を含む大きい Entity のインスタンスを作る、という実装は結構やっています。
    • ScriptableObject と可換にしようとするとかなり死ねるんですが、それは別のお話。
  • Entity のリストを持つ Entity や、JSON のノードとして幾つかの種類の Entity を持つ Map (Dictionary) 的な Entity なんてのもバンバン使います。

  • これは、そうかも知れません。
  • 私は、Entity や Model の構造を変更する時に UseCase を修正したくなかったので、Translator 層に退避させた感じです。
  • 実際、CAFU を使ったとしても Translator 層ナシでも実装できます。

適用させやすいゲームとそうじゃないゲームがある?

  • RPG などの方が適用させやすいのは事実です。
    • というか、 適用させる価値が高い と言い換えられます。
  • ですが、本質的にはどんなゲームにも適用できるかな?と思っています。
  • アクションゲームで言うと、複雑なアクションの結果生じた「データの計算」やその「データの入出力」などの ルールを定義 しているに過ぎないため、見た目やアクションやエフェクトの複雑さとは切り離すコトが可能かなぁ?とは思っています。
    • やったことないので何とも言えませんがw

もはや Unity 関係なくね?

  • はい。その通りです。
  • というか、そこを目指して開発しました。
  • 元々普遍的な概念なので、「部分最適することで Unity に当てはめた」という感じですね。

Entity…?

  • 懇親会でも何名かの方から聞かれたのですが、DDD の文脈に於ける Entity とは意味合いが違います。
  • 元ネタのブログ では「An entity can be an object with methods, or it can be a set of data structures and functions.」とあるので、私は外部データ定義レイヤーとしてネーミングしました。

Repository と DataStore の分離

  • 私は必要に応じて Repository レイヤーのサブクラス的な扱いで DataStoreResolver 的なモノを用意し、「利用する DataStore を選択するためのサブレイヤー」を追加定義することがあります。
    • DataStoreResolver 自体も疎結合にする必要があるので、結構面倒ですがw
  • この辺は、まだ画一的な方法が見出せておらず、プロジェクト毎に自由にやらせてしまっているのが実情です。
  • 良案募集中です。

適用するの難しそう…。初速鈍そう…。

  • はい。容易ではありません。
  • 正直、初速は良くありません。
  • が、慣れると、めちゃめちゃ速いです。
  • 1本小さめのアプリ書き上げるくらいまで使うと、その後の開発は相当楽になります。
    • 元々弊社プロダクトは、小さめのアプリを大量に作って一つのアプリにする必要があるという特性があるので、その辺をかなり意識して作りました。

密結合なアセットどーすんの?

  • 私はロジックにガッツリ介入してくるようなアセットは殆ど使っていません。
  • Unity の文脈で言うところの Component に該当するアセット(View レイヤー)はバンバン使っちゃって良いと思いますが、 View 以降のレイヤーに介入してくるアセットは、相当厳選して入れています。

コードジェネレータないの?

  • あります
  • CAFU Core を yarn でインストールすれば依存として勝手にインストールされます。
    • 2018/06/07 現在、Unity 2018.1 でちょっと問題があるので修正中です。

CAFU のテストなくね?

  • はい。書きます。
  • ドキュメントやサンプルとともに喫緊の課題として積んでおります…orz

所感

  • mixi さんのイベントスペースがとても良く、感動しきりでした。
    • 最大90名程度の収容力
    • 2面スクリーン
    • ワイヤレス映像出力
    • 生放送・録画機材
    • おしゃれ感
    • etc...
  • イベント自体は、公開直後に満席になり、増席してもなお人が増え続けて、ピーク時には定員90名のところに158名もの方にご応募いただくという、「このテストケースは書けなかったわーw」という状況にまでなりました。
  • 流石に90人(スタッフ入れたら100人超えていたかも?)の前でフルセッション話すのは(多分)はじめてだったので、登壇直前までガッチガチに緊張していましたが、会場の空気が精神的な意味で暖かく、落ち着いて話すことができました。
    • スライドが100Pを超えていたので、早口にはなっていたと思いますがw
  • 結果、ほとんど無言ドタキャンもなく、セッションは勿論のこと懇親会も大いに盛り上がり、「大成功」と言える勉強会になったと思います!
  • メインで動いてくれた青木ととくんや登壇者の皆さんや現場で設営・撤営・録画など多大なご協力をいただいた mixi 社の方々に、この場を借りて改めて深く御礼申し上げます!ありがとうございました!!!