ランダムテストは、ランダムで独立した入力 を生成する ことによってプログラムをテストするブラックボックス ソフトウェアテスト 手法です。出力結果はソフトウェア仕様と比較され、テスト出力が合格か不合格かが検証されます。[ 1 ] 仕様 がない場合は、言語の例外が 使用されます。つまり、テスト実行中に例外が発生した場合は、プログラムに欠陥があることを意味します。これは、偏ったテストを回避する方法としても使用されます。
無作為検査の歴史 ハードウェアのランダムテストは、1971年にメルビン・ブロイアー によって初めて検討され、その有効性を評価する最初の試みは、 1975年にプラティマとヴィシュワニ・アグラワル によって行われた。[ 2 ]
ソフトウェア分野では、デュランとンタフォスが1984年にランダムテストを研究した。[ 3 ]
ランダムテストの理論的基礎としての仮説検定の使用は、ハウデンが『機能テストと分析』 で説明した。この本には、故障率が 1/n 以下であるという信頼度を少なくとも 1-1/ nにするために必要なテスト数 n を推定するための簡単な公式の開発も含まれている。この公式は、 n log n の下限であり、控えめな故障率の境界に対して控えめな信頼度を得るために必要な、多数の故障のないテストを示している。[ 4 ]
概要 次のC++関数を考えてみましょう。
int myAbs ( int x ) { if ( x > 0 ) { return x ; } else { return x ; // バグ: '-x' であるべき } } この関数のランダムなテストは、{123, 36, -35, 48, 0} のようになります。バグが発生するのは、値 '-35' の場合のみです。結果を確認するための参照実装 がない場合、バグは見過ごされる可能性があります。しかし、次のようなアサーション を追加して結果を確認することができます。
void testAbs ( int n ) { for ( int i = 0 ; i < n ; i ++ ) { int x = getRandomInput (); int result = myAbs ( x ); assert ( result >= 0 ); } } リファレンス実装は、例えば、パフォーマンス向上のために単純なアルゴリズムをより複雑な方法で実装する場合などに利用可能です。例えば、シェーンハーゲ・シュトラッセンアルゴリズム の実装をテストするには、整数に対する標準的な「*」演算を使用できます。
int getRandomInput () { // … } void testFastMultiplication ( int n ) { for ( int i = 0 ; i < n ; i ++ ) { long x = getRandomInput (); long y = getRandomInput (); long result = fastMultiplication ( x , y ); assert ( x * y == result ); } } この例は単純な型(単純な乱数生成器を使用できる)に限定されていますが、オブジェクト指向言語を対象としたツールは通常、プログラムを探索して生成器(その型のオブジェクトを返すコンストラクタまたはメソッド)をテストして見つけ、乱数入力(同じ方法で生成されたもの、または可能であれば擬似乱数生成器を使用して生成されたもの)を使用してそれらを呼び出します。このようなアプローチでは、ランダムに生成されたオブジェクトのプールを維持し、生成されたオブジェクトを再利用するか新しいオブジェクトを作成するかの確率を使用します。[ 5 ]
ランダム性について D. ハムレットによるランダムテストに関する画期的な論文によると
[…]「ランダムテスト」の技術的、数学的な意味は、テストデータの選択において「システム」が明確に欠如していることを指し、異なるテスト間に相関関係がないことを意味します。[ 1 ]
長所と短所 ランダム検査は、以下の長所から高く評価されている。
使用コストが安い。テスト対象のプログラムについて高度な知識を必要としないからだ。 偏りがない:手動テストとは異なり、一部のコードに対する誤った信頼のためにバグを見落とすことがない。 バグ候補を迅速に見つけることができ、テストセッションの実行には通常数分しかかかりません。 ソフトウェアの仕様が適切であれば、実際のバグを発見できる。 以下の弱点が指摘されています 。
基本的なバグ(例えば、ヌルポインタの 逆参照)しか検出できません。 その精度は仕様の精度に依存するが、仕様は通常、不正確である。 バグを見つけるための他の手法(例えば静的プログラム解析 )と比較すると、その性能は劣る。 各テスト実行で異なる入力がランダムに選択されると、同じテストがランダムに合格または失敗するため、継続的インテグレーションに問題が生じる可能性があります。 [ 6 ] ランダム性に頼るよりも、ホワイトボックス方式で手作業で構築したテストで関連するすべてのケースを慎重に網羅する方が良いと主張する人もいる。[ 6 ] 低い故障率に対する低い信頼度を得るには、非常に多くのテストが必要になる場合があります。たとえば、故障の確率が1/100未満であると少なくとも99%の信頼度を得るには、459回の故障のないテストが必要になります。[ 4 ]
ランダム検査の種類
ランダムな入力シーケンスの生成(つまり、メソッド呼び出しのシーケンス) ランダムなデータ入力シーケンス(確率的テストとも呼ばれる) - 例:ランダムなメソッド呼び出しシーケンス 既存のデータベースからのランダムなデータ選択
ガイド付き vs. ガイドなし 探索を導くヒューリスティックを持たない、無方向性のランダムテスト生成 指向性ランダムテスト生成 - 例えば「フィードバック指向性ランダムテスト生成」[ 7 ] および「適応型ランダムテスト」[ 8 ]
実装 ランダムテストを実装するツールの例:
QuickCheckは、元々は Haskell 向けに開発されたものの、他の多くの言語にも移植された有名なテストツールで、モデルに基づいてランダムなAPI呼び出しシーケンスを生成し、実行ごとに真であるべきシステムプロパティを検証します。Randoop - テスト対象クラスのメソッドとコンストラクタの呼び出しシーケンスを生成し、それらからJUnitテストを作成します。 Simulant - Clojure ツール。さまざまなエージェント(例えば、行動プロファイルが異なるユーザー)の行動を統計モデルに基づいてシミュレーションし、すべてのアクションと結果をデータベースに記録して、後で調査および検証できるようにする。 AutoTest - EiffelStudioに統合されたツールで、同名の研究プロトタイプに基づく契約を使用してEiffelコードを自動的にテストします。[ 5 ] York Extensible Testing Infrastructure (YETI) - さまざまなプログラミング言語(Java、JML、CoFoJa、.NET、C、Kermeta)を対象とした、言語に依存しないツールです。 GramTestは、Javaで書かれた文法ベースのランダムテストツールで、入力文法を指定するためにBNF表記法を使用します。
批評 ランダムテストは実際には特殊なニッチにしか使われていない。これは主に、効果的なオラクルがめったに利用できないためだが、運用プロファイルや擬似乱数入力値の生成に困難があるためでもある。[ 1 ]
テストオラクル とは、結果がプログラム仕様と一致するかどうかを検証するためのツールです。操作プロファイルとは、プログラムの使用パターンに関する情報であり、どの部分がより重要であるかを示すものです。
契約を持つプログラミング言語やプラットフォーム(Eiffel、.NET、JML、CoFoJaなどのJavaのさまざまな拡張機能など)では、契約が自然なオラクルとして機能し、このアプローチは成功裏に適用されています。[ 5 ] 特に、ランダムテストは、手動検査やユーザー報告よりも多くのバグを発見します(ただし、種類は異なります)。[ 9 ]
参考文献 1 2 3 リチャード・ハムレット (1994)。「ランダムテスト」。ジョン・J・マルシニアック編『ソフトウェア工学百科事典』 (第1 版)。ジョン・ワイリー・アンド・サンズ。ISBN 978-0471540021 。 ↑ Agrawal, P.; Agrawal, VD (1975年7月1日). 「冗長でない組み合わせ論理ネットワークに対するランダムテスト生成方法の確率的解析」. IEEE Transactions on Computers . C-24 (7): 691–695 . doi : 10.1109/TC.1975.224289 . ↑ Duran, JW; Ntafos, SC (1984年7月1日). 「ランダムテストの評価」. IEEE Transactions on Software Engineering . SE-10 (4): 438–444 . doi : 10.1109/TSE.1984.5010257 . 1 2 ハウデン、ウィリアム (1987). 機能的プログラムテストと分析 . ニューヨーク: マグロウヒル. pp. 51–53 . ISBN 0-07-030550-1 。1 2 3 "AutoTest - ソフトウェアエンジニアリング講座" . se.inf.ethz.ch . 2017年 11月15日 取得 . 1 2 「テストデータをランダムに生成するのは悪い習慣ですか?」 stackoverflow.com 2017 年 11月15日 取得 。 ↑ Pacheco, Carlos; Shuvendu K. Lahiri; Michael D. Ernst; Thomas Ball (2007年5月). "フィードバック指向型ランダムテスト生成" (PDF) . 第29回国際ソフトウェア工学会議 (ICSE'07) . pp. 75–84 . doi : 10.1109/ICSE.2007.37 . ISBN 978-0-7695-2828-1 ISSN 0270-5257 ↑ TY Chen; F.-C. Kuo; RG Merkel; TH Tse (2010)、 「適応型ランダムテスト:テストケースの多様性の芸術」 、 Journal of Systems and Software 、 83 (1): 60–66 、 doi : 10.1016/j.jss.2009.02.022 、 hdl : 10722/89054 ↑ Ilinca Ciupa; Alexander Pretschner ; Manuel Oriol; Andreas Leitner; Bertrand Meyer (2009). 「ランダム テストで発見された欠陥の数と性質について」。 ソフトウェアテスト、検証、信頼性 。21 : 3–28。doi : 10.1002 /stvr.415 。
外部リンク アンドレア・アルクリによるランダムテスト。 ポートランド州立大学名誉教授リチャード・ハムレットによるランダムテスト。論文末尾に貴重な参考文献リストが掲載されている。 Cunningham & Cunningham, Inc. のランダムテストに関するWikiページ