プログラマが知るべき97のこと/コードを見る人のためにテストを書く
読者の中に「製品版コード一つ一つについて、必ず自動化テストを書くようにしている」という人はどのくらいいますか?もしそうしているのなら、素晴らしいことだと思います。「テストは、いつもコードを書き始める前に書くようにしている」という人がいれば、さらに素晴らしいです。どちらも、ソフトウェアエンジニアリングの最先端のプラクティスをいち早く取り入れている、と言えるでしょう。ただ、テストを書くのはいいとして、そのテストは果たして「良いテスト」と言えるでしょうか。良いテストが書けているかを、どうやって見極めればいいのでしょうか。そのために「自分は誰のためにテストを書いているのか」と自らに問うてみるのは1つの方法でしょう。もしその答えが「自分のため。バグ修正の労力を少しでも減らすため」あるいは「コンパイラのため。コンパイル作業を円滑に進めるため」だったとしたら、良いテストが書けている可能性は低いと言えるでしょう。では一体誰のためにテストを書けばいいというのでしょうか。それは、「コードを見る人のため」です。
良いテストはドキュメントのようなはたらきをします。テスト対象となるコードについて知るのに役立つのです。「このコードはどう動くのか」を教えてくれるのが良いテストです。良いテストの条件を簡単にまとめると次のようになるでしょう。
- コンテキスト、出発点、満たすべき事前条件がわかる。
- ソフトウェアがどのように起動されるかがわかる。
- 期待される結果と、確認すべき事後条件がわかる。
以上の3つは利用シナリオごとに少しずつ違ってきますが、それが逐一わかるのが良いテストでしょう。コードについて知りたいと,思った人がテストを見た時、上の3つの点についてわかればいいわけです。それによって、ソフトウェアの動きを変化させるために何を変えればいいかもわかるでしょう。テストを見ることで、上の3つの間の因果関係も明確にわかるのが望ましいと言えます。
テストに関しては、何を見せるかだけでなく、「何を見せないか」も重要になります。たとえば、テストのコードが多すぎれば、読む人は些細なことにばかり囚われて肝心なことが理解できなくなる恐れがあります。できる限り、メソッドコールなどの重要な部分以外以上の3つは利用シナリオごとに少しずつ違ってきますが、それが逐一わかるのが良いテストでしょう。コードについて知りたいと,思った人がテストを見た時、上の3つの点についてわかればいいわけです。それによって、ソフトウェアの動きを変化させるために何を変えればいいかもわかるでしょう。テストを見ることで、上の3つの間の因果関係も明確にわかるのが望ましいと言えます。
テストのテストをするのも良いことです。製品版コード(ただし本物ではなくコピー。テストが終わったら破棄する)にあえてエラーを混入させ、期待どおりにそのエラーが検知されるかを確認するのです。単にエラーの発生が報告されるだけでなく、どういうエラーが起きていてどう対処すればいいかがわかる報告になっていることも確認しましょう。テストが、コードを理解する上で本当に役立つものになっているかも確認しておくべきでしょう。それを確認するには、コードについてよく知らない人にテストを読んでもらうしかありません。読んでもらった上で何がわかったかを話してもらうのです。その時に話されることをじっくりと聞くことが大事です。よく話を聞いて、もし何か「これはよくわかっていないな」と感じたことがあったとすれば、それはおそらく、その人に知性が欠けているせいではありません。テストが十分にわかりやすいものになっていないということです(その後、役割を交代し、テストを読んでくれた人の書いたテストをこちらが読んでみても面白いでしょう)。