Design for Testability(テスト容易性のための設計)
1. 原則
テスト可能な設計を意識する
- コードを実装する際、ユニットテストを容易に作成・実行・検証できるように設計する
- 単体でテスト可能なコンポーネントを構築する
- 外部依存を分離し、隔離された環境で振る舞いを検証できる状態にする
2. 根拠
バグの早期発見
- テストしやすいコードは、ユニットテストの作成を促し、実装段階でのバグを早期に発見できる
リファクタリングの安全性
- テストが容易な設計は、安心してコードの改善や変更(リファクタリング)を行える
設計の改善:
- テスト容易性を追求することで、自然と以下の原則に従うことになる
- 単一責任の原則(SRP): 一つのクラスや関数が一つの役割のみを持つ
- 依存関係逆転の原則(DIP): 具象クラスに依存せず、抽象に依存する
3. 指針
依存性の注入(DI)
- 外部の依存オブジェクト(データベース、APIなど)を直接インスタンス化せず、コンストラクタやメソッドを通じて受け渡すこと
- これにより、テスト時にモックやスタブに置き換えることが可能になる
具象クラスへの依存を避ける
- 依存する際は、具体的な実装クラスではなく、インターフェースや抽象クラスに依存する
グローバル変数の使用を避ける
- グローバルな状態はテストの独立性を損なうため、極力使用しない
4. 注意事項
複雑性の増大
- 過度にテスト容易性を追求すると、間接的なコードが増え、かえって全体の複雑性を高める
コストと利益のバランス
- すべてのコードに完璧なテスト容易性を適用するのではなく、ビジネスロジックや重要な機能に焦点を当てる
テストの対象外
- UIや外部サービス連携など、テストが困難な部分は、統合テストでカバーすることも検討する
privateメソッドのテスト
- privateメソッドは外部から直接テストするのではなく、publicなメソッドを通じて振る舞いを検証する
- privateメソッドが複雑な場合は、それを独立したpublicなクラスに切り出すことを検討する