テストしやすいコードを書くために
本記事では、よりテストしやすいコードを書くために意識していることを紹介します。テストのしやすいコードを書くと、バグの減少につながるだけでなく、品質向上や開発効率改善にも繋がります。
テストケースの考え方や、良いテストの書き方についてもご紹介しているので、こちらもあわせてご覧ください。
テストしやすいコードとは?
そもそも、テストしやすいコードとはどういったものでしょうか。私は、次のような特性を持つコードがテストしやすいと感じます。
- モジュール性:コードが小さな単位に分割され、それぞれが独立して機能する
- 明確性:コードの意図が明確で、理解しやすい
- 独立性:外部システムや状態に依存せず、単独でテストが可能
これらの特性を備えたコードは、バグの発見が容易でありスムーズにテストコードを書くことができます。次の章では、上記の特徴を簡単に実装できる原則をご紹介します。
テストしやすいコードを書くための原則
1. 関心の分離(Separation of Concerns, SoC)
関心の分離とは、一つのコンポーネントやクラスが「単一の責務のみ」を持つように設計することを意味します。
この原則を守ることで、コードの変更が他の部分に影響を与えにくくなり、個別のユニットテストが容易になるというメリットがあります。
✴︎ 悪い例
class UserManager:
def create_user(self, username, password):
hashed_password = self.hash_password(password) # パスワードのハッシュ化
self.save_to_database(username, hashed_password) # データベースに保存
self.send_welcome_email(username) # ウェルカムメール送信
上記のコードは ユーザーの作成・パスワードのハッシュ化・データベース保存・メール送信 という 複数の責務を1つのクラスで行っています。
✴︎ 良い例
class UserManager:
def create_user(self, username, password):
hashed_password = PasswordHasher.hash(password)
UserRepository.save(username, hashed_password)
EmailService.send_welcome_email(username)
このように役割ごとにクラスや関数を分けることで、ユニットテストがしやすくなります。
2. 依存性の注入(Dependency Injection, DI)
外部の依存関係を直接コード内で生成するのではなく、外部から注入(インジェクション)することで、より柔軟でテストしやすいコードになります。
✴︎ 悪い例(依存関係を直接作成)
class UserService:
def __init__(self):
self.repository = UserRepository() # 直接依存
このように UserService が UserRepository を直接作成してしまうと、テスト時にモックやスタブを利用するのが難しくなります。
✴︎ 良い例(依存性の注入を適用)
class UserService:
def __init__(self, repository):
self.repository = repository # 外部から注入
これにより、テスト時にモックを渡すことができるため、データベースを使わずにユニットテストが可能になります。
mock_repository = Mock()
service = UserService(mock_repository)
3. 副作用の少ないコードを書く
副作用とは、関数の実行によって グローバル変数を変更する、データベースに書き込む、ファイルを変更するなどの目に見えない影響を指します。
副作用の少ないコードを書く方法として、
- 関数型プログラミングの原則を取り入れる
- 可能な限り純粋関数(Pure Function) を使う(引数が同じなら、常に同じ結果を返す)
- それぞれの責務を明確にする
などが挙げられます。
詳細に関してはこちらの記事をご覧ください。↓
まとめ
テストしやすいコードを書くための原則を3つご紹介しました。
- 関心の分離を意識し、1つのクラスや関数に複数の責務を持たせない
- 依存性の注入を活用し、テストの柔軟性を高める
- 副作用を最小限に抑え、テストの信頼性を向上させる
これらの原則を取り入れることで、テストしやすく、保守性の高いコードを書くことができます。
次のセクションでは、実際にテストを書いてみる方法について解説します。ユニットテストの基本から、モックの活用まで詳しく見ていきましょう!