ブラックボックステストうんぬん

 アプリケーションをテストする場合、ソースコードに含まれるロジックが見えている状態で、分岐や行カバレッジをカバーしていることを保証するために項目の設計を行なうホワイトボックステストと、機能の外部要件やインタフェースだけが見えている前提で行なうブラックボックステストという方法がある。

 通常、"機能テスト"とか"結合テスト"とかいった場合に、ホワイトボックステストで実施するケースはあまり多くないように思う。

 しかしながら、ブラックボックスなテストのみで、「この試験で大丈夫」と言うためには中身を知っていないといけないのではないか。もしくは、「たぶん大丈夫」というレベルを許容するかのどちらかではないのか。

例を考えつつ、なんでそんなことをいまさら思うのかというあたりをぐだぐだと書いておこうと。

結合テストとか、ブラックボックスの場合、たいていの場合外部要件を基にしつつ、

会員状態が「非会員」かつ、入会時点が "2006-01-31 23:59:59" のとき、入
会処理を行なうと、"300円のキャッシュバック"が処理されること。

会員状態が「非会員」かつ、入会時点が "2006-02-01 00:00:00" のとき、入
会処理を行なうと、"300円のキャッシュバック"が処理されないこと。

などというテスト項目を立てていくことになる。上の例は極端にシンプルなもので、「1月末までに入会すると300円のキャッシュバック!」という要件を正しく処理できているかどうかを確認するために、「境界テスト」というテスト項目設計技法?を使って立ててみた例である。このような項目でブラックボックステストの要項は構成されていることが多い。

この2項目のうち、前者は「○○のとき、△△となることを(試験を実施して)証明せよ」という問題である。しかし、後者の本当の意図は「○○でないとき、△△とならないことを(試験を実施して)証明せよ」ということになる。

では、このケースで「○○ではない」とはどういうことかといえば、"1月末までに入会しなかった"ということになるが、このケースは無数に存在する。屁理屈をこねると、"2006-02-01 00:00:00のときだけうまくいくロジックである可能性があり、もしそうなっていた場合はこの試験項目には合格するだろうが、要件は達成していない"ということになる。ということは、試験をもって証明するには総てのケースを網羅してテストする必要があるが、これは事実上無限集団のケースということになってしまいもちろん非現実的だ。なので(少なくともシステム開発を行なう上では)この証明を行なうのは大変困難であり、「悪魔の証明」などと酷似しているのではないか。

ところで前者も同様にある1ケースでしか試験していないのに要件通りであるとはいえない。「ある条件を満たすときに(必ず)要件どおりに動作する」というのは裏返してみれば「ある条件を満たすときには、要件どおりに動作しないケースはない」ということを証明することになるので、結局のところ悪魔の証明的な問題を含んでいる。

つまり、all or nothingで、「100%正しく動作する」ことをブラックボックステスト項目だけで論証することは不可能なのではないか? ということになる。

境界テストは、システムのロジックが(おそらくは)ある境界値を元に2値を比較して分岐するような構造 (if a<b then, elseのような) である場合は有効に機能する。しかし分岐の「実装のされ方」についてホワイトボックスでなければ「境界テストで確実である」ことは証明できない。

結局のところ、ブラックボックスのみで項目を立てた試験というものは(ロジックに対しての)仮定をたてた上で、システムが確かに動作する可能性を高めていくフェーズということまでしか言えない。この項目リスト単体で「確実である」ことは証明することはできないのだから、「充分である」かどうかは、何らかの指標、モデルへの合致と、レビュアーの主観にすら依存する。

おそらく、これは許容せざるを得ない。

許容できないとするならば、悪魔の証明に対抗できない限り、項目を無限に追加してしまう可能性が出てくる。

「このテスト項目で想定しうるケースをすべてカバーできているのですか」
「しかし、この項目で足りないと思われるところがあるのでしたら提示してみてください」
「たとえば2006-02-01 00:00:01のときはどうですか」
(項目追加  上に戻る)

ってこんなことをやるのはナンセンスに違いない。でもどの程度まで? なるほどと思うところがあれば追加するのは当然だし、そうでないと思うのであれば、それは暗黙の仮説が個々人の間に出来ているから?etc...

で、「不確実性があることはもちろん!」とするか、ブラックボックステストの内容を検証する場合には、「中身を見る」ようにすればいいのではないかと思うわけです。

外部要件を元にテスト項目を立て、項目の立て方(境界テストとか)の前提となっている仮説(2値の比較で分岐しているはず)が、実物と一致するかを検証するために、ソースコードレビューなどを実施すれば安心なのだ。

品質は細部に宿る!(突然)