【90】コードを見る人のためにテストを書く

ジェラルド・メサローシュ(Gerard Meszaros)

 読者の中に「製品版コード一つ一つについて、必ず自動化テストを書くようにしている」という人はどのくらいいますか? もしそうしているのなら、素晴らしいことだと思います。「テストは、いつもコードを書き始める前に書くようにしている」という人がいれば、さらに素晴らしいです。どちらも、ソフトウェアエンジニアリングの最先端のプラクティスをいち早く取り入れている、と言えるでしょう。ただ、テストを書くのはいいとして、そのテストは果たして「良いテスト」と言えるでしょうか。良いテストが書けているかを、どうやって見極めればいいのでしょうか。そのために「自分は誰のためにテストを書いているのか」と自らに問うてみるのは 1 つの方法でしょう。もしその答えが「自分のため。バグ修正の労力を少しでも減らすため」あるいは「コンパイラのため。コンパイル作業を円滑に進めるため」だったとしたら、良いテストが書けている可能性は低いと言えるでしょう。では一体誰のためにテストを書けばいいというのでしょうか。それは、「コードを見る人のため」です。

 良いテストはドキュメントのようなはたらきをします。テスト対象となるコードについて知るのに役立つのです。「このコードはどう動くのか」を教えてくれるのが良いテストです。良いテストの条件を簡単にまとめると次のようになるでしょう。

 以上の 3 つは利用シナリオごとに少しずつ違ってきますが、それが逐一わかるのが良いテストでしょう。コードについて知りたいと思った人がテストを見た時、上の 3 つの点についてわかればいいわけです。それによって、ソフトウェアの動きを変化させるために何を変えればいいかもわかるでしょう。テストを見ることで、上の 3 つの間の因果関係も明確にわかるのが望ましいと言えます。

 テストに関しては、何を見せるかだけでなく、「何を見せないか」も重要になります。たとえば、テストのコードが多すぎれば、読む人は些細なことにばかり囚われて肝心なことが理解できなくなる恐れがあります。できる限り、メソッドコールなどの重要な部分以外は、隠しておくようにするといいでしょう。その意味で「メソッドの抽出」リファクタリングは非常に有効といえます。テストには、その利用シナリオについて説明するような意味のある名前をつけるようにすべきです。その名前を見れば、テストの読み手は、リバースエンジニアリングをしなくても、シナリオがどういうものであるかわかります。テストメソッドだけでなく、テストクラスやクラスメソッドにも、少なくとも出発点がわかるような、あるいはソフトウェアの起動のされ方がわかるような名前をつけます。こうしておけば、メソッド名をざっと見ていくだけで、だいたいのテストカバレッジがわかります。名前が長すぎて読みづらいという問題が起きないようであれば、テストメソッド名は「そのメソッドに期待される実行結果」も同時にわかるようにしておくといいでしょう。

 テストのテストをするのも良いことです。製品版コード(ただし本物ではなくコピー。テストが終わったら破棄する)にあえてエラーを混入させ、期待どおりにそのエラーが検知されるかを確認するのです。単にエラーの発生が報告されるだけでなく、どういうエラーが起きていてどう対処すればいいかがわかる報告になっていることも確認しましょう。テストが、コードを理解する上で本当に役立つものになっているかも確認しておくべきでしょう。それを確認するには、コードについてよく知らない人にテストを読んでもらうしかありません。読んでもらった上で何がわかったかを話してもらうのです。その時に話されることをじっくりと聞くことが大事です。よく話を聞いて、もし何か「これはよくわかっていないな」と感じたことがあったとすれば、それはおそらく、その人に知性が欠けているせいではありません。テストが十分にわかりやすいものになっていないということです(その後、役割を交代し、テストを読んでくれた人の書いたテストをこちらが読んでみても面白いでしょう)。