2008年03月06日
_ ランダムテストの使い方
ランダムテストというものがあります。 プログラムをテストするにあたってランダムな入力を使うという ものです。テスト入力作を作るにはコーナーケースをできるだけ 網羅することが重要ですが、人手でそれをするのは難しいことです。 そのため入力はランダムにしてテスト数を増やすことでそれに対応 しようというのがランダムテストの基本的な考えかたです。 詳しくは QuickCheck などを参照、ってことでいいんでしょうか。
さて、ここで問題になるのがどのようにしてプログラムの出力を 検証するかです。ランダムな入力をプログラムに食わせるだけ ではテストにはなりません。その出力の正しさを判定する必要が あります。しかし、ランダムな入力に対する出力を生成できる プログラムというのはまさにそのテスト対象に他なりません。 テストをするためにはテスト済みのプログラムが必要、となって しまうわけです。これでは話になりません。ではランダムテストを 有効活用するためにどうすればよいのでしょうか。
一つの方法としては、出力結果が満たすべき条件をうまく考えて それを検証する方法があると思います。 例えば、ソートプログラムのテストをすることを考えましょう。 すると、要素が3個の配列を昇順ソートした結果が満たすべき性質として
- 出力の要素は3個でなければならな
- 出力が [x, y, z] と書きあらわされるなら x <= y かつ y <= z でなければならない
などといった条件をチェックするのです。こうすればランダムな入力 に対する検証が可能になります。
もう一つの方法として、より簡単で自明だが遅いという実装 の出力と比較する方法です。やはりソートプログラムのテストを することを考えましょう。この場合はまずバブルソートあたりを 実装してしまいます。で、その後目的のソートプログラムを 書き、それの出力とバブルソートの出力を比較するのです。 これなら入力がランダムでもテスト可能です。別の例として、 GPGPUのような高速だが特殊なプログラミングが必要という ものを考えます。この場合普通のCで別実装を書いて それを比較するという方法があります。 特殊なプログラミングのための処理系やハードウェアの挙動に 難しい点がある(高速性のためにわかりやすさが犠牲になっている というのはありそうな話です)という場合に特に有効でしょう。
ただ、これらの方法にも問題はあります。一つ目の方法では 例えばn個の配列に対し0がn個という出力を得られる プログラムでもテストが通ってしまいます。また、 簡単に検証できる条件なるものが常にあるとは限りません。 ソートのようなアルゴリズム的な問題の 場合には比較的そのような条件が見いだしやすいのですが、 世の中そういうプログラムばかりではありませんし。
二つ目の方法にしても、より簡単で自明な実装なるものが 常にあるとは限りません。世の中にはバブルソートを実装 するような仕事だってあるのです。 簡単な実装のほうが間違っていたらどうしようもないという 問題もあります。
とまあランダムテストは時と場所をかなり選びますが、 うまくはまれば非常に役にたちます。 二つ目の方法は私が実践しているので、ある程度うまくいくことは 保証できます。たいしたことのない文章ですが、なんらかの 役に立ってくれればありがたいことです。