単体テストの考え方/使い方

発売されたばかりの単体テストの考え方/使い方を年末年始の読み物として読んだ。これまでいくつかのテスティングフレームワークを使ってきたものの、単体テストとはどうあるべきかといったツールによらない本質的な部分の理解をおろそかにしてきたので手にとった。

テスト・ダブル、スタブ、モックのそれぞれの違いなど今まであいまいに理解してきた用語をしっかり定義した上で、良い単体テストに求められる観点を4つ提示し、それに基づいてモックをどのように使うか、単体テストのそれぞれの手法をどう評価するかといった解説があり、単体テストにとどまらずヘキサゴナルアーキテクチャや関数型アーキテクチャといったアーキテクチャがテスタビリティに与える影響まで解説されている。

個人的に印象に残ったことを列挙してみる。

  • テストコードもプロダクションコード同様に書いた時点から負債になるので、たくさん書けば良いというものではなく、ドメインロジックを中心に書く。
  • テストケース間で共通する処理をコンストラクタやsetUpでまとめると、テストケース間の結合度が上がるし読みにくい。その代わりに、Object MotherパターンやTest Data Builderパターンを使いArrangeフェーズのコードを共有するのが望ましい。
  • テストメソッドのメソッド名はドメインエキスパートが理解できるようにテストする振る舞いを書く。実装に結びついたメソッド名は避ける。
  • 実装に結びついたテストコードはリファクタリングによって壊れやすくなる。
  • モックはテスト対象から外部に向かう出力を模倣して検証するためのもので、スタブは外部からテスト対象への入力を模倣するためのもの。スタブへの検証は実装の詳細を検証することになり、リファクタリングで壊れやすくなる。
  • 出力値ベースの単体テストが最も質が高い。出力値ベースでテストできるようにするためには、ロジックと副作用を切り離し関数型プログラミングのスタイルで実装する。

当初の目論見通り、ツールによらない本質的な部分の理解が深まり、これまで当たり前に実践してきた単体テストのやり方が間違っていたことに気づけたので、とてもいい本だった。