単体テストの「単体」が指すものや単体テストの流派について
この記事はNE Advent Calendar2023 17日目の記事です。
はじめに
開発チームのメンバーと自動テストについて話していたとき、人によって「単体」が指しているものやモックを使う対象について認識が違ってそうだなと思って単体テストの考え方/使い方を読んでみての感想です。
古典学派とロンドン学派
テストについての考え方として古典学派、ロンドン学派と呼ばれる考え方がある。
「単体」の定義
- 古典学派
- 1単位の振る舞い
- ロンドン学派
- 1単位のコード=1クラス
テストダブルを使う対象
- 古典学派
- 共有依存
- ロンドン学派
- 共有依存と可変依存(=不変依存以外のすべて)
ロンドン学派のメリット・デメリット
- メリット
- テスト対象のクラス以外をスタブ/モック化しており細かい粒度で検証できるので、テストがこけたときにどこが原因か分かりやすい
- 依存が複雑なときにもスタブにすればいいので、複雑なデータ準備をせずに実行できるテストを書ける。
- デメリット
- 詳細な実装に依存することになるので偽陽性が起きやすい
- テストコードを見たときに実装について検証しているので、振る舞いの理解がしづらい
上記を受けての感想
読前
読む前の自分のスタンスはそんなに明確ではなかったが、振り返ってみると「単体」といえばクラスをイメージしてはいたことが多い。
テストダブルの適用については、そのときそのとき考えるといった感じで共有依存はモックにしたい。可変依存も準備が簡単な依存ならプロダクションコードをそのまま動かすけど割とモック化してた。
なのでどちらかというとロンドン学派的な考え方ではあったかなと。
読後
テストに複雑な準備が必要ということはプロダクションコードの設計に問題があるので、ロンドン学派のメリットは本質的な解決ではないという本書の主張には同意だった。
また自動テストの目的としてソフトウェアの持続的な成長というのを考えれば、実装の詳細よりも振る舞いに焦点をあてたほうがいいというのにも同意。
古典学派の考え方に則るにはリファクタリングが必須
プロダクションコードの設計が都度見直されないまま肥大化してテストコードもないという時期があって後からテストだけ書いたみたいな経緯があると、全部はリファクタリングしきれず共有依存以外もモック化しているロンドン学派的な単体テストが多くなるのは自然だなと思う。
DB操作などの副作用を起こす処理とビジネスロジックが分離されていない複雑な依存関係になっているところは、単にモックをやめるだけだとテスト実行に時間がかかりすぎてしまうので副作用を分離するような設計を考えないといけない。
コードベースが大きく複雑だと再設計も難しいだろうけど、でもやはりリファクタリングとテストはセットでおこなっていかないといけないのだろう。
まとめ
基本的には古典学派の考え方に賛同しつつ、実現のためには設計とリファクタリングを頑張らないといけないなという感想。
Discussion