テストの基礎

良いテスト、悪いテスト

テストの「良し悪し」

テストの「良し悪し」を論じるにもさまざまな観点がありますが、代表的なものを以下に記載します。

<良いテストとは>
テスト対象の要素(機能など)を漏らさず、網羅している
バグが検出できる
テストケースの数がより少ない(コスト・期間がより低く抑えられる)

<悪いテストとは>
テスト漏れがあり、バグを見過ごしている
バグが検出できない
テストケースの数が必要以上に多い

上記を口語調で表すと、以下のようになります。

<良いテストとは>
テスト対象を漏れ抜けなく網羅して、バグをより多く検出することを、より少ないテストケースで実現する。

<悪いテストとは>
テストに漏れがあり、バグが検出できず、その割にはテストケースがやたらと多い

テストの第一義は、「漏らさない」こと

機能仕様書に書かれていることを機械的にテストケースに落としていくだけでは、ほぼ間違いなくテストケース漏れを起こします。
また、機能仕様書に書かれていることをテストするだけではまったく不十分です。その理由は、機能仕様書に、開発で考慮すべき・テストすべきことが漏らさず書かれているとは限らないためです。
機能仕様書に記載されているものはもとより、書き洩らしていることや曖昧なことも、すべて網にかけて体系的に網羅することが、テストで第一に必要なことです。

テストケースを現実的な量に抑え込む

テストケースは無限に存在し得ます。
無限とは「非常にたくさんある」という意味ではなく、文字通りに無限、上限が無い、ということです。
テストに用いるデータは実にさまざまなパターンがあります。
何かのパラメータの組合せが、多い時には何十億通りに及ぶこともあります。
さらに、時間というタイミングの要素を考慮に入れると、テストケースは無限に存在し得ることが容易に想像できるでしょう。

しかし、当然ながら、テストにかけられるコスト、人員、期間は有限です。
無限に存在し得るテストケースを、現実世界で実行するためには、有限のテストケース数まで上手に落とし込んでやる必要があります。
テストケースは、上述のように「漏らさないように網羅すること」が第一義として必要ですが、「何をテストしないのか」を設計することも必要です。

バグを検出する可能性を高める

いくつかある「テストの目的」のうち、テストが果たすべき重要な役割は「バグを見つけ出し、それを修正する」ことです。
ただ漫然と機能仕様書に書かれている内容を踏襲するだけのテストでは、バグは見つけられません。 バグは狙って見つけ出しにいくことも必要です。
バグには生態とも言えるものがあります。

  • 開発者が間違いやすいポイント
  • それらバグを見つけ出しやすいテストのやり方

これらを考え併せて、バグを見つけに行くテストを設計します。
バグを狙って出していく行為は、釣りに似ています。

<釣りの場合>
狙った魚の生態から、潜んでいそうなポイントを特定し、そのポイントに、魚が食いつきやすい仕掛けを投げ入れて、魚を釣り上げます。

<テストの場合>
狙ったバグの生態から、プログラム中に潜んでいそうなポイントを特定し、そのポイントに、バグが検出されやすいテストを実施して、バグを検出します。
機能仕様書に書かれているものをたどっていくテストも必要ですが、それだけでは足りません。テスト対象が正常に動作せず、期待と異なる異常な振る舞いをする条件や操作を行い、バグを狙って検出しにいくテストも必要です。

プログラムが期待どおりに正しく動作することを確認するのを「チェッキング」と呼び、バグを狙って検出しにいくものを「テスティング」と呼ぶことがあります。

まとめ

「良いテスト」とは何でしたでしょうか。いま一度、以下に再掲します。

  • テスト対象を漏れ抜けなく網羅して、バグをより多く検出することを、より少ないテストケースで実現する。

「漏れ抜けなく網羅」するためには、テスト対象を体系的にテストケースに落とし込んでいく技術が必要です。
「バグをより多く検出」するためには、バグが発露しやすい条件や操作を設定するための技術や発想力が必要です。
「漏れ抜けなく網羅」「バグをより多く検出」を実現するのに、テストケースが膨大なものになってはいけません。

限られた工数・期間内に収めるために、テストケースをより少なくするための技術が必要です。
逆に、漫然とテストケースを作ると、「テストに漏れがあり、バグが検出できず、その割にはテストケースがやたらと多い」ことになります。
良いテストを行うためには、そもそも「良いテストとはどんな姿か」を明確にし、その上で、テストを設計するのが必要不可欠です。