ソフトウェアにおけるテストの有効性と限界

ソフトウェア開発において、テストは必要ですが、品質をあげるという意味では場合によっては機能しません。何故なら、ソフトウェアの品質は、ほとんど設計に依存するからです。


例えば、1〜Nまでの和を出力するプログラムを考えてみます。この要件を持つ設計は1通りでないことは明らかです。その意味のとおりNまでを足していく設計、再帰的にN以下の和を足す設計、数学の公式を使う設計、いろいろあると思います。


各設計に基づいて実装されたプログラムに必要なテストのパターンもその設計に応じて変わってきます。例えば、上のような設計に基づいていれば数パターンのテストで十分でしょう。

問題となるのは、設計が「複雑」な場合です。N=1なら1、N=2なら3…というように無数に分岐したプログラムの正しさを確認するには、無限のパターンが必要です。このケースは極端な例ですが、実際の要件は十分複雑で、問題の本質を捉えられなければこのような設計になってしまうことも多いと思います。


以上の事から、テストの有効なパターン数というのは、設計の「複雑さ」に依存するといえます。
全体を通して、複雑さというのは3種類考えられます。

  • (1) 問題(要件)の本質的複雑さ
  • (2) 設計(、実装)の複雑さ
  • (3) テストパターンの複雑さ

自明ですが、(2)は(1)よりも小さくすることはできません。そして、(3) は、(2)と同程度であるとき有効です。つまり、複雑さが抑えられた設計では、テストの複雑さは要件の本質的複雑さと同程度で済み、コストが抑えられるということです。

バグを極力減らして、品質が高いソフトウェアを開発するには、複雑さが極力抑えられたシンプルな設計にする必要があります。反対に、よく設計が考えられないまま開発されたソフトウェアは、複雑さを無駄に大きくして多くのバグを内包し、テストのコストを高くします。さらに、カバーできなかったバグは運用へ送られ…ということです。


テストが有効に働くのは設計が「シンプル」に行われたときで、そうでなければ膨大なテストパターン(=コスト)を必要とし、品質を確保できなくなってしまうのではないかと思います。