「保護」できるテストとは
では、「保護」できるテストとは何でしょうか? それは「単体テスト」、それも「自動実行できる単体テスト」です。コードを変更した際の有益なテストとして、ぱっと思いつくのは「回帰テスト」であり、業務システムには用意されていることが一般的ですが、回帰テストだけでは十分ではありません。
回帰テストは多くの場合「アプリケーションインターフェースに対して行われる」ものです。それは、改修や機能追加がすべて終わってから実行するものとして用意されています。もちろん、回帰テストには重要な意味があるのですが、コードの変更の際には、「フィードバックが得られるまでに時間がかかる」という問題があります。回帰テストは改修や機能追加がすべて終わり、実際に稼働する直前の確認のために行うものであり、コード変更をしながら随時動かして確認するものではないからです。
一方、単体テストは、当然コードのある部分だけに対して実行できます。単体テストが適切な粒度(システムの振る舞いの面から見て、最も原始的な単位)で用意されていれば、「開発中にフィードバック」が得られ、コード変更が意図したとおりに動作するのか、他の場所の振る舞いを変えてしまっていないかの確認をしながら進めることができます。また、単に変更するだけでなく、徐々に質の向上するシステムに変えていくためのリファクタリングを安全に行うことも可能にします。レガシーコードの変更には、自動実行できる単体テストが、重要な鍵を握るのです。
既存のコードは苦痛?
皆さんが携わっているシステム開発は、新規開発でしょうか。それとも既存システムの改修や機能追加でしょうか。統計では、企業のシステム予算のうちの6~7割は既存システムに使われているそうなので、既存システムの改修や機能追加に携わっている方が多いのではないでしょうか。そして、これは私が常々感じていることなのですが、既存システムの方が新規システムとくらべて、なぜか経験の少ないプログラマが投入される傾向にあるように思います(実際に、情シス部門の知人に聞いても同様の意見でした)。既存システムには、予算が多く使われているにも関わらず、経験の少ないプログラマが投入されているということになります。
効果的なソフトウェア変更は、効果的な手術と同じで、実際には高いスキルが必要です。特にレガシーコードに携わる場合には、アプリケーションを広範囲に理解し、さまざまなプログラム設計の手法に精通していなければなりません。既存コードの修正の難しさは、前述したとおりです。
しかし、技術書で書かれていることの多くは新規開発を対象にしており、既存コードの変更に直接参考になるようなものはほとんどありませんでした。経験の少ないプログラマは、ちょっとした変更であっても、試行錯誤と残業を繰り返しながらやっとのことで終わらせている、そんな状況が多いのではないでしょうか。
本書の著者は、そのような状況に苦しんでいる多くのチーム、多くのプログラマを見てきており、そのような人々の仕事を少しでも楽しいものに変えたい、という強い思いがあって本書を執筆しています。本書が、多くの人が苦しんでいる既存コードの変更というテーマを取り上げているのは、楽しかったはずのプログラムがいつの間にか苦痛になっている、そんな状況を変えたいという強い思いが背景にあるのです。
「ベスト」を目指すだけではシステムはよくならない
『レガシーコード改善ガイド(Working Effectively With Legacy Code)』は、以上の根底にある考えに基づき、「コードを理解し、テストで保護し、リファクタリングし、機能を追加するための手法」がまとめられています。これまでの技術書の多くが「ベスト」を目指す方法を説明したものであるのに対して、本書は、「ベター」を目指す大切さが説かれていることが大きな特長です。まずはベター、つまりテストが可能な状態にさえなっていれば、いずれベストの状態にできる、という考え方です。この観点で書かれている点で本書は画期的だと思います。
次回からは、具体的な手法の概略を紹介していきます。もし、それらの手法について、もっと深く、詳しく知りたいと感じていただけたのなら、ぜひ『レガシーコード改善ガイド』を手にとってみてください。