読書感想文「単体テストの考え方/使い方」
はじめに
書いているテストコードに対して、以下の経験をした方にはこの本をおすすめします。
- リファクタリングのたびにテストが壊れて大変
- 書いたテストコードが役に立ってるかわからない
- 単体テストは通ってるのに、結合時にエラーがたくさん出てしまう
この本で筆者はテストコードにモックを多用するモック主義を批判しています。モック主義に対する流儀として古典主義があります。筆者はこの古典主義をこの本で推奨しています。実は自分もモック主義者でしたが、この本を読んで古典主義者に傾きつつあります。
モック主義と古典主義の違いについて
-
モック主義の単体テスト
- 一つのクラスを検証することに重点を置く
- これは、テストの失敗時に問題のあるクラスを迅速に特定できる利点がある
- テスト対象クラスを隔離するため、モックを用いて1つのクラスを隔離する方針がとられる
- 一つのクラスを検証することに重点を置く
-
古典主義の単体テスト
- 1つの振る舞いを検証することに重点を置く
- モックの使用は以下を満たすため必要最低限する
- 実行時間が短いこと
- 他のテストケースと依存せず、隔離された状態で実行されること
良い単体テストはリファクタリングに強い
本書で書かれている良い単体テストの定義は以下です。
- 退行に対する保護
- リファクタリングへの耐性
- 迅速なフィードバック
- 保守がしやすい
以上のうち、「リファクタリングの耐性」は特に重要と私は考えます。
プロダクトの成長にはリファクタリングが不可欠だからです。本書でも触れられていますが、リファクタリングせずにプロダクトコードの無秩序を放置していると、次第に新規追加や修正が困難になります。
モック主義の単体テストは「リファクタリングへの耐性」が無いです。この単体テストはホワイトボックス的です。1つのクラスにモックを差し込み、テスト対象クラスとモック間のコミュニケーションをテストします。外部から振る舞いとして見えない実装の詳細をテストすることになり、振る舞いを変えずに内部の技術的詳細だけを変更するリファクタリングとは相性が悪いです。実際に開発していて思ったことですが、プロダクションコードが壊れていないのにテストが失敗することがよく起こります。このような失敗は偽陽性と呼ばれ、大変問題があります。テスト対象が正しく振舞っていいるにも関わらずテストが失敗するようなことが続くと、開発者はそのことに慣れてしまいます。正常性バイアスによりテスト結果を重要視しなくなります。やがて開発者は正当な失敗であってもテストの失敗を無視するようになり、問題のあるコードが本番環境に持ち込まれてしまうことに繋がります。
一方、古典派の単体テストは「リファクタリングへの耐性」があります。対象の振る舞いの最終的な結果を確認するためブラックボックス的だからです。リファクタリング耐性のあるテストコードがあれば、開発者は退行に対して強い自信を持ってリファクタリングに取り組むことができます。プロダクト成長のためにも古典主義のアプローチは大変重要だと感じます。
良いテストコードを書くにはこの本がおすすめ
本書では、古典主義のテストコードを実現するための実践的な内容が載っています。7章にはハンズオン形式の記述(C#)があり、手を動かしながら学ぶことができます。
また、コードを書くだけでなく、それを継続的に保守していくことの重要性も強調されています。テストコードの読みやすさを向上させるための手法や、アンチパターン等も記載されており、保守性の高いテストが書けるようになります。
総じて、本書は実践的なアドバイスや具体的な手法を提供しており、単体テストの考え方や使い方について深く理解したい人にとって価値のある一冊です。
Discussion