概要
「単体テストの考え方/使い方」を読みました。 感想を書きます。
前提
目的
- ソフトウェアテストの実力を上げるための一環として、ユニットテストについても学ぶことにした
- 自分の持っているユニットテストに対する考え方を裏付ける、または、非難するような書籍だと考えて、興味を持った
- 勉強会の課題図書だった
前提知識
ユニットテストについて、以下の考え方を持っています。
- ユニットテストはドメイン層に書くべきで、アプリケーション・サービス書くべきではない。アプリケーション・サービスに複雑なロジックを持っているなら、ドメインオブジェクトにするべき
- テストダブルにモックは基本的に使わない。代わりスタブを利用する。DB を除くアプリケーション外部とのやりとりを模倣するときにモックを使う
- DB と接続するコンポーネントにおいて、モックを使うべきではない。必ず本物の DB を利用したテストを実装する
ユニットテスト関連の本は以下の本を読んでいました。
ソフトウェアテスト関連では、以下の書籍を呼んでいました。
- 知識ゼロから学ぶソフトウェアテスト【改訂版】
- ソフトウェアテスト技法練習帳 ~知識を経験に変える 40 問~
- ソフトウェア品質を高める開発者テスト 改訂版 アジャイル時代の実践的・効率的でスムーズなテストのやり方
- 【この 1 冊でよくわかる】 ソフトウェアテストの教科書[増補改訂第2版]
読了時間
勉強会が 5 回あり、1 回で準備に 5 時間、勉強会の時間が 2 時間程度だったので、35 時間ほどかかりました。
感想
良いユニットテストはどうやって書くのかに焦点を当て、ユニットテストの目的であるプロジェクトの成長を持続可能なものするを達成させることを可能にする名著でした。
この本を読み理解し業務のコードに適用することで、間違いなく良いユニットテストから生まれる恩恵を受け、プロジェクトの成長が持続可能なものになります。
より多くの人がユニットテストを書くときに、この本の考え方を持ってほしいと考えています。
また、個人的に持っていたユニットテストだけでなく設計に対する考え方について根拠が得られ自信を持ちました。
良かった点を 4 つにまとめたので、それぞれ記述していきます。
1. ユニットテストに関する用語の整理ができる
1 つ目は、ユニットテストを書くための用語の整理ができることです 良いパターンだけでなくアンチパターンについても整理されます。 用語には下記が挙げられます。具体的な意味は zenn の scrap「「単体テストの考え方/使い方」用語メモ」に軽くまとめました。
- 優れたテストスイート
- 古典学派の観点における単体テスト
- 良い単体テストを構成する 4 本の柱
- テスト・ダブルの種類
- 単体テストの 3 つの手法
- 観察可能な振る舞い
- プロダクションコードの 4 つの分類
- モックのベストプラクティス
これらの整理ができることで、どのようなユニットテストを目指すべきなのか明確になります。 個人の範囲で意識して実践することで恩恵を受け入れられるのはもちろんのこと、チーム内においてユニットテストの共通認識を用語レベルから合意が取れれば、間違いなくプロジェクトが成功すると思いました。 また、これらの考え方の合意がとれたチームで働いてみたいと思いました。
2. コントローラ(アプリケーション・サービス)でユニットテストに書くかどうかについて
2 つ目は、コントローラ(アプリケーション・サービス)にユニットテストを書くかどうかについてです。
これは自身が個人開発と業務の両方で考えていた部分だったので、ちょうど知りたかった部分でした。
結論からいうとコントローラ(ヘキサゴナルアーキテクチャにおけるアプリケーション・サービス)にユニットテストを書くべきではないでした。
コントローラはロジックを持たせず、ドメインオブジェクトにロジックを持たせてドメインオブジェクトでユニットテストするという考え方は、自分の考え方と一致していたためとても満足でした。
私は理由を聞かれると困っていたのですが、本書ではコードの複雑さやドメインにおける重要性の観点と協力者オブジェクトの数の観点からユニットテストなのか統合テストなのかの基準について解説します。
この 2 つの観点から作る 4 象限の図は非常にわかりやすく納得感がありました。
もちろん、必ずしもすべてのロジックをドメイン層に記述できるわけではないのですが、そういった場合は必ず存在することとその解決策についても触れられていて非常に参考になりました。
3. 設計観点からのテスタビリティ
3 つ目は、設計観点からのテスタビリティについても触れられていることです。
本書ではヘキサゴナルアーキテクチャと関数型アーキテクチャは、隠れた入出力をアーキテクチャのコアな部分から外側に分離しようとすることについて説明します。
それらを徹底することで良いユニットテストが記述できるのは、その通りだと思いました。
アーキテクチャについてさまざまな記事がありますが、層の名前じゃなくてこの内容の方が重要だと考えています。テスト観点からも触れられていたので非常に良かったです。
この本をきっかけに、今後はアーキテクチャについて議論するときに、当たり前のように隠れた入出力を分離することについて議論されるようになってほしいです。
加えて、関数型プログラミングならエラー型もシグネチャでき、よりテストしやすくなることについても触れられていたので、この本をきっかけに関数型プログラミングがもっと流行ってくれないかと思いました。
4. モックの使い方について
4 つ目はモックの使い方についての解説が非常に良かったです。 個人的に、一般的なユニットテストの説明において、以下のように言われることが多く疑問を持つことが多かったです。
- 依存先のテスト・ダブルにはモックを使うのが当たり前のように言われる
- テスト・ダブルとモックが同一の意味として使われる
- DB の検証でモックを使われる
この本では、モックとはなんなのか、いつモックを使うべきなのか、モックを使うことでコミュニケーション・ベース・テストになってしまうことの何が問題なのか解説してくれます。
モックを過度に使いすぎたプロジェクトで発生した問題を経験したことがあったので、納得しながら読み進めていました。
モックを説明するときや利用する際には、本書のモックの説明を一読してほしいです。
モックは、さまざまなフレームワークに搭載されているため過度に使われてしまう傾向があると考えています。
あまりにも一般的すぎて、誤ったモックの使い方の危険性について説明し納得させるのが個人的に難しかったです。
結果的に妥協することも多かったのですが、この本の内容や根拠づけは説明し代替手段を提案できるような気持ちになれました。
以上になります。ほかにも良い部分はあったんですが、特に印象を残った部分を記載しました。 詳細は本書を手に取って読んでみてください。 以前から考えていた部分が言語化されていて、答え合わせをするように読み進められました。 この本で言語化できたので、用語を借りつつ、学んだことをチームレベルに浸透させていきたいです。
次に関連で勉強すること
いったん、ユニットテストや設計関連の勉強は終わりにして、ソフトウェアテストの知見を溜めていきます。 設計論も大事ですが、ユースケースを満たすテストの考え方についても知見を得たいのでソフトウェアテストを学んでいきます。
具体的には、下記の本を検討しています。