この記事の内容は技術書を読んだ感想や個人的な考察です。
書籍情報
質の高いテストを行い、ソフトウェアに価値をもたらそう!
著作者名:Vladimir Khorikov
編集者名:須田智之
Unit Testing Principles, Practices, and Patternsの翻訳書。
なぜこの本を読んだのか
ソフトウェア開発において単体テストは基本的に必要なものだと考えています。
単体テストが無いと、変更に対して自信を持つことができません。代わりに時間がかかるE2Eレベルの手動テストをしたり、バグが多く発生してその修正が必要になることでスピードが低下します。また、スピードの低下をカバーするために、リファクタリグなど保守性に関わる作業を後回しにしたり、テストケースを省いたりすることで質が低下します。
このようにスピードの低下が質の低下させ、質の低下がスピードの低下を招くという悪循環が発生し、開発を継続することが困難になっていきます。
このように考えて単体テストを積極的に実施していますが、単体テストの価値やトレードオフ、良し悪しの判断など、曖昧な部分が多くあったのでこの本を手に取りました。
当書から得られたこと
単体テストの定義
そもそも、単体テストとはどういったテストのことを言うのか?統合テストとの違いは何か?という部分が不明確でした。そして、これは私だけではなく、人によってテストの分類の認識が異なる、ということがよくあるようです。1
当書では、まず第1部で2つの学派(古典学派、ロンドン学派)の違いについて分析しつつ、単体テストを3つの性質で明確に定義しています。そして、この明確な定義を土台として以降の話が展開されていきます。
テストについて議論する際、こうしたテストの分類について認識を揃えることが大切なのだと思います。
良い単体テストの定義とトレードオフ
単体テストにも良し悪しがあり、悪い単体テストが増えてしまうと、開発を持続させることが難しくなってしまいます。では「良い単体テスト」とはどのようなものでしょうか?
当書では"良い単体テストを構成する4本の柱"として定義しています。そして様々なプラクティスについて、この4本の柱に対してどのような影響があるのか、という観点で説明されています。
また、4本の柱のトレードオフをどのように考えるべきか、という指針も得ることができました。
モックをどのように使うのか
私が初めて書いたテスト・コードはモックが多く使われていて、テストに対して自信が持てなくなったり、テスト・コードが長く保守するのが難しい状態になってしまいました。
こうした問題を回避して適切のモックを活用するための、モックの対象(依存)にはどのようなものがあるのか、どのような依存をモックに置き換えるべきなのか、といった点について学ぶことができました。
プロダクション・コードの設計
テスト・コードとプロダクション・コードは対になるものです。私が初めて書いたテスト・コードが良いものにならなかったのは、テストに関するスキルが不足していただけではなく、プロダクション・コードの設計が良くなかった事も大きいです。
そのプロダクション・コードの分類や、どのようにプロダクション・コードをリファクタリングして単体テスト(あるいは統合テスト)を改善していくか、という点について学ぶことができました。
考察
テストのフェーズの区切り
当書ではAAAパターンの各フェーズを示すコメントについて、空白行で区切れるなら不要、としています。
これについては基本的に同意しますが、GitHub CopilotなどのAI支援を受ける場合は、一律で各フェーズを示すコメントを入れたほうが、その恩恵を受けやすいように感じています。
管理下にない依存をモックする
当書ではモックする対象として「管理下にない依存」としていますが、Next.jsで開発していて、次のような構造になることがありました。
- テスト対象
- Web API(管理下にある)
- データベース(管理下にない)
- Web API(管理下にある)
このような構造の場合、テスト対象をテストするにあたり、Web APIへのリクエストはモックすべきかどうかを考えました。私の考えとしては、このWeb APIは管理下にないデータベースへの中継であるので、「実質管理下にない」としてモックするのが良いと考えています。
- テスト対象
- Web API(管理下にある)
- 管理下にある依存
- 管理下にない依存
- Web API(管理下にある)
また、このように管理下にある依存と管理下にない依存を両方含む場合も同様に、実質管理下にないと考えています。
そして、Web APIをテスト対象としてテストする場合に、管理下にない依存だけをモックに置き換えます。
テスト・コードのテスト
単体テストをするにあたって、テスト・コードのテストはどうするのか、という疑問がありますが、残念ながら当書では扱っていませんでした。これについて是非著者の意見を聞いてみたいところです。
私の考えとしては、TDDのように最初に失敗することを確認したり、一時的プロダクション・コードに誤りを入れて確認する方法があると思います。
まとめ
当書はページ数400と、エヴァンス本(約500ページ)に近い分厚さです。一度通して読んだだけで全て身につくものではないですが、その一部を取り入れて実践するだけでも役に立っている実感があります。これからも繰り返し読み返すことになるでしょう。
また当書で紹介されていた、依存の管理に関する書籍2や、著者のブログ3も興味を惹かれる内容なので読んでみたいと思います。
-
サバンナ便り〜自動テストに関する連載で得られた知見のまとめ〜 https://forkwell.connpass.com/event/281043/ ↩
-
Dependency Injection Principles, Practices, and Patterns https://www.manning.com/books/dependency-injection-principles-practices-patterns ↩
-
Enterprise Craftsmanship https://enterprisecraftsmanship.com/ ↩