imog

主にUnityとかの事を書いています

テストコードについての文書を書いていた

色々決めごとをするときは社内にissueなりwikiなり残すのですが、これは外に公開してもいいんじゃない?と思ったので公開します。

今回は「Unityにテストコードを導入する」ときの文書です

なぜテストコードを導入するのか

往々にしてプロダクトの要件は常に変化します。一ヵ月前の仕様が変わることも珍しいことではありません。仕様が変わればコードの修正は必要です。つまり、コードは必ず変化するという前提で書く必要があります。

コードが変化すると、その周辺のコードに少なからず影響を与えます。場合によっては全然関係ないと思っていたところに飛び火することもあります。それらを予め人間がすべて把握するのは経験則からくる職人技に近いものなので、非常に難易度が高いです。

テストコードを書くと、変更を加えた際に起きる影響をある程度可視化してくれます。 プロダクトの規模が大きくなるほど開発速度は落ちていきますが、テストコードはその減速率を下げるのに役立ちます。

テストコードを書くメリットは以下の2点です

品質を把握する

テストそのものが品質を上げてくれるわけではありません。テストコードは現状のプロダクトの品質がどんなものなのかを可視化してくれます。この部分が適切に動いているのか、この部分に変更を加えるとどうなるのか、など。品質の可視化は機能追加、リファクタリングの判断材料となり、素早い意思決定が行えます。

テストがないコードは品質が悪いのではなく品質がわからないので、どこを直すべきか、どこの処理を手厚くすべきかという判断が難しくなり、結果的に開発効率が落ちてしまうと考えています。

精神的障壁の排除

影響範囲の見えないコードの修正はメンタル的によろしくないです。 根本原因を解決すべきとわかっていても、影響範囲が見えない場合、リスクを減らし最小工数で抑えるために一旦場当たり的な対応を取りがちです。これはもちろん有効に働く場合もありますが、上記のネガティブな理由から選択すると、未来で同じ問題にぶつかってしまいます。

テストコードにより影響範囲が可視化されていると、根本原因の解決はどのくらいの影響を与えるのかというのがある程度見えることで「なんだか大変そう・・」という精神的障壁を超えた上で判断ができるようになります。

導入するためには?

テストコードを書くためには、ビューとロジックが分離されている必要があります。(そうしないとめっちゃ書きづらい) これは別issueのMV(R)Pアーキテクチャ導入 #1125 によって実現できると考えてます。

また、シングルトンはテストするのが非常に面倒です。 refs シングルトンパターンの誘惑に負けない

この問題は、シングルトンをやめて依存性の注入(DI)を行うことで解決できます。UnityだとZenjectというライブラリが有名です。

ユニットテスト

Unityに依存しないPure Classのテストです。これはEditModeテストを導入します。実はいくつか実装済みです。 - 例 xxxxx

Zenjectを導入した場合、バインド処理が必要になるのでZenjectに付属の ZenjectUnitTestFixture を継承して書く

refs - Unity で ユニットテストをする http://blog.kakeragames.com/2016/02/17/unity-test-unit.html

インテグレーションテスト

MonoBehaviorなどUnityに依存したコードのPlayModeテストを書く。やり方はもうちょっと詰めていく。

unity-uitestというライブラリがあったのでこれを使えばアウトゲームのシーンUIの自動テストは書けそうな気がするが要調査