<輪読会> オブジェクト指向実践ガイド -第9章費用対効果の高いテストを設計する-
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
第9章費用対効果の高いテストを設計する
- 変更可能なコードを書く為の3つのスキル
- オブジェクト指向設計の理解
- コードのリファクタリングスキル
リファクタリングとは、ソフトウェアの外部の振る舞いを保ったままで、内部の構造を改善していく作業を指します。MartinFowler『新装版リファクタリング─既存のコードを安全に改善する』(児玉公信・友野晶夫・平澤章・梅澤真史共訳、オーム社、2014)
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5252-5255). Kindle 版.
- テストを書く能力
9.1意図を持ったテスト
- 一般的なテストのメリット
- テストを持つことの根拠として、最も一般的に言われていることは、テストはバグを減らすとか、文書になるだとか、テストを「最初」に書くことでアプリケーションの設計がより良いものになる、といったことでしょう。
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5274-5276). Kindle 版.
テストをすることの真の目的は、設計の真の目的がまさにそうであるように、コストの削減である
テストがなかった場合にかかるバグの修正に必要な時間や文書を書く時間、アプリケーションを設計する時間などに比べて、テストの記述、メンテナンス、実行に多くの時間がかかるのであれば、テストを書く価値はありません。
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5277-5281). Kindle 版.
- テストにコストがかかることの解決方法
テストをやめることではありません。うまくなることです。テストから優れた価値を得るには、意図の明確さが求められます。そして、何を、いつ、どのようにテストするかも知らなければなりません。
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5288-5290). Kindle 版.
テストの意図を知る
- 本書におけるテストの真のメリット
- バグを見つける
- バグの初期段階での修正は、いつでもコストの削減になる
- 仕様書となる
- 人の記憶と異なり、忘却や改ざんに依存せず、唯一信用できる設計の仕様書となる
- 設計の決定を安全に遅らせる
- 抽象的な(インターフェースに依存する)テストを書くことで、設計の決定を安全に遅らせることができる
- 抽象を支える
- より良い設計に近づけていく為に、徐々に抽象度を上げる形でコードを修正していく
- テストをすることで、あらゆる抽象のインターフェースを記録する
- 設計の欠陥を明らかにする
- テストのセットアップに苦痛が伴うようであれば、コードはコンテキストを要求しすぎていることが分かる
- 1つのオブジェクトをテストするために、ほかのオブジェクトをいくつも引き込まなければならないのであれば、そのコードは依存関係を持ちすぎてる
- テストを書くのが大変なのであれば、ほかのオブジェクトから見ても再利用が難しい
- 上記なような課題が見えてきたら、疎結合なテストを書くべきである
- バグを見つける
何をテストするかを知る
一般規則として、オブジェクトは、自身のパブリックインターフェースを構成するメッセージに対して「のみ」テストをするべきである
パブリックインターフェイス以外をテストする必要がないからといって、それらのテストをまったくしなくてよいというわけではない
- テスト対象に関するまとめ
いつテストをするかを知る
テストの方法を知る
テストの方法
テストをするときのオブジェクトのカテゴリー
- 自身がテストをするオブジェクトであること
- そのほかのものすべて
9.2受信メッセージをテストする
- 受信メッセージ
- オブジェクトのパブリックインターフェースを構成し、原則テストを必要とする
- 依存されていない受信メッセージは削除する
パブリックインターフェースを証明する
受信メッセージのテストに求められること
- 考えられ得るすべての状況において正しい値を返すことを証明すること
オブジェクトが単一責任になっていないケースでのテストの懸念
- テストの実行時間がかかる
- 想定外の結果が起こる可能性が高まる
9.3プライベートメソッドをテストする
パブリックインターフェイス以外は、送られたことがテストされるべきである
テスト中ではプライベートメソッドを無視する
- プライベートメソッドのテストをしないことを支持する理由
- パブリックでもテストされる事が多く、冗長になる為
- プライベートメソッドは、依存関係がある場合が多いので不安定である
- 依存関係があるので、テスト対象オブジェクト以外も記述する必要が出る可能性があり、テストの文脈が伝わらない
プライベートメソッドのテストをするという選択
- 設計の決定を遅らせることが目的の場合
9.7まとめ
- テストを書くのが難しい時は設計に問題がある
- 上記は依存関係が複雑であり、疎結合でない為難しくしてしまっている
- 設計全体が疎結合で単一責任になっている(パブリックインターフェイスの)時は、いかなる状況でも期待する値が返ってくるか検証するテストを書く
- 依存関係が複雑(プライベートメソッド)の場合は、基本的にはテストをしない
- 上記でも例外があり、設計の決定を遅せるのが目的の場合は、テストを記述する方が良い時もある。ただし、そのテストは「振る舞い」をテストすべきである
- テストの内容が具象すぎる時は、ダックタイピングやモジュール・継承の考えを用いてテストそのものを疎結合なものとする
参考書籍
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 | Sandi Metz, 髙山泰基 | 工学 | Kindleストア | Amazon