こんにちは、@p1ass です。 最近はどっぷり Splatoon 3 にはまっています。
さて、ここ 1 年近く読み進めていた『Google のソフトウェアエンジニアリング』をようやく読み終えました。 大ボリュームで時間がかかってしまいましたが、学びが多くある本だったので感想をまとめようと思います。
脆いテストに苦しんでいた自分に自動テストのプラクティスを教えてくれた
本書では様々なトピックについて詳細に語られていますが、一番良いと思ったのはテストのトピックです。 ちょうど脆いテストに苦しんでいた自分に様々な気づきを与えてくれました。
脆い(brittle)テストとは
本書では、「期待結果を過剰に指定したり大規模で複雑な定形コードに依存したりするテスト」 のことを脆いテストと呼んでいます。 もし、ある機能に 5 行の変更を行ったときに何十個もの無関係なテストが破綻したことがあるなら、それは脆いテストの煩わしさを感じたことがあるということになります。
脆いテストに苦しんでいた経験
私は過去にこのような脆いテストに苦しんだ経験があります。
変更が実際のバグを全く持ち込んでいないにも関わらず、大量のテストが FAIL してしまうということがありました。 コードの変更よりもテストの修正の方に多くの時間を取られ、本来生産性を高めてくれるはずの自動テストが生産性を落としてしまうという本末転倒な形になっていました。
特に、モックを使ったテストコードが脆いテストになってしまっていたことが多かったです。 テストを書いた当初は「モック使えば簡単にテストできて便利〜」と思っていたのですが、いざリファクタリングの変更を加えようとしたときには、そのテストはあまり役に立たないものと化していました。
脆いテストを生み出さないためのプラクティス
本書ではそういった脆いテストに対する様々なプラクティスを提供しています。 それらのプラクティスに共通するゴールとして、「理想のテストとは変化しないテストである」 を掲げています。
テスト対象システムの要件が変わらない限り書かれたテストが二度と変更が必要とないようなテストであれば、元々あったテストが FAIL = コードがバグっているか、テストコードが仕様変更に追従できていない ことになります。 テストの修正は最低限になり、生産性を保ちながらシステムの品質を保てます。 この考えは私にとって新鮮なものでした。今までテストで意識するところといえば、境界値テストなど何をアサーションするか程度で、テストの生産性や保守ということについて考えていませんでした。 本書では Google での今までの経験から、長年テストコードを保守していくためにはこういったことを意識しながらテストを書いていくべきだという気づきを与えてくれました。
具体的なプラクティスはいくつか紹介されていましたが、特に
- 相互作用ではなく、状態をテストせよ
は非常に納得感のあるプラクティスでした。 呼び出しに応じて期待される一連の動作を検証するのではなく、メソッドを呼び出した後にシステムがどのような状態になっているかを検証することで脆いテストを防げるというプラクティスです。 相互作用を検証しようとすると、過度にモッキングフレームワークを使うことになり、結果として内部実装に依存したテストコードになってしまいます。
状態をテストしようとすることで、モックではなく本物のオブジェクトを使うようになり、結果として公開 API 経由でのテストになってもろいテストを防ぐことができます。 これはまさに私が抱えてた課題に対する答えであり、実践したところとてもワークするプラクティスでした。 これを意識するだけでテストの保守は格段にしやすくなると感じました。
ぶっちゃけ Google レベルでしか実現できないこともある
他にも様々なトピックはありましたが、ぶっちゃけ我々が真似するのは厳しいんじゃないかというトピックも結構ありました。
例えば、依存関係管理や CodeSearch といった内製ツールは最たる例です。 社内標準を作るための専用の人材やチームがないと、ここまで頑張るのは厳しそうだなぁという気持ちになりました。 こういったところは話半分に読みつつ、もし活かせるところがあれば部分的に参考にするのが良いんじゃないかと思いました。
終わりに
あんまり長く書くとあれなのでピックアップしてブログにまとめましたが、他にも役に立つ章はたくさんあります。 エンジニアリングのプラクティスだけではなく、チームやリーダーの振る舞いやドキュメント、文化など様々な側面の内容が書かれています。
自分が興味ある分野だけではなく他の章も読むことで新たな発見が得られる本なので、分厚いですがぜひ全部読むことをおすすめします。