web-dev-qa-db-ja.com

ソフトウェアテストの正式な/数学的な理論はありますか?

グーグルの「ソフトウェアテスト理論」は、Wordのソフトな意味での理論を提示するだけのようです。私は、数学、情報理論、またはその他の科学分野の感覚で理論として分類できるものを見つけることができませんでした。

私が探しているのは、テストとは何か、使用されている概念、テストケースとは何か、テストの実現可能性、テストの実用性、テストの範囲、正式な定義/説明です。コードカバレッジなど.

更新:また、私は、正式な検証と私が尋ねた内容との関係について、直感的にはわかりませんが、明らかに何らかの関係があります。

12
Erik Kaplun

ソフトウェアのテストの背後にある数学を探る本について...得るべき独創的な本は Art of Computer Systems Performance Analysis:Techniques for Experimental Design、Measurement、Simulation、and Modeling

1991年に最初に発行されましたが、パフォーマンス分析、シミュレーション、測定のみに焦点を当てた応用数学の本であるため、今日でも人気があります。

8
Dakotah North

優れたオンラインリソース(これらのトピックに関する英語版のWikipediaの記事は改善可能である傾向があります)を指すことはできませんが、基本的なテスト理論についても取り上げた講演をまとめることができます。

テストモード

単体テスト統合テストのようなさまざまなクラスのテストがあります。単体テストは、それ自体で行われたコヒーレントなコード(関数、クラス、モジュール)が期待どおりに機能することを表明し、統合テストは、そのような複数の部分が正しく連携することを表明します。

テストケースは既知の環境であり、コードの一部が実行されます。特定のテスト入力を使用するか、他のクラスをモックします。次に、コードの動作が予想される動作と比較されます。特定の戻り値。

テストは、バグの存在を証明するだけで、すべてのバグの不在を証明することはできません。テストでは、プログラムの正確性に上限を設定します。

コードカバレッジ

コードカバレッジメトリックを定義するには、ソースコードを制御フローグラフに変換して、各ノードにコードの線形セグメントを含めることができます。これらのノード間の制御フローは、各ブロックの最後にのみあり、常に条件付きです(条件の場合、ノードAに移動し、ノードBに移動します)。グラフにはone開始ノードとone終了ノードがあります。

  • このグラフでは、ステートメントカバレッジは、すべてのノードに対するすべての訪問済みノードの比率です。完全なテストを行うには、ステートメント全体を網羅するだけでは不十分です。
  • 分岐カバレッジは、CFG内のノード間のすべての訪問済みエッジとすべてのエッジの比率です。これではループのテストが不十分です。
  • パスカバレッジは、すべてのパスに対するすべての訪問済みパスの比率です。パスは、開始ノードから終了ノードまでのエッジのシーケンスです。問題は、ループの場合、パスの数が無限になる可能性があるため、完全なパスカバレッジを実際にテストできないことです。

したがって、条件カバレッジを確認すると便利なことがよくあります。

  • 単純な条件カバレッジでは、各アトミック条件は1回trueと1回falseになりますが、これは完全なステートメントカバレッジを保証するものではありません。
  • 複数条件カバレッジでは、アトミック条件はtruefalseのすべての組み合わせを採用しています。これは完全なブランチカバレッジを意味しますが、かなり高価です。プログラムには、特定の組み合わせを除外する追加の制約がある場合があります。この手法はブランチカバレッジを取得するのに適していますが、デッドコードを見つけることはできますが、wrong条件に起因するバグを見つけることはできません。
  • 最小の複数条件カバレッジでは、各アトミック条件と複合条件は、真と偽になります。それはまだ完全なブランチカバレッジを意味します。これは複数の条件カバレッジのサブセットですが、必要なテストケースは少なくなります。

条件カバレッジを使用してテスト入力を構築する場合、短絡を考慮する必要があります。例えば、

_function foo(A, B) {
  if (A && B) x()
  else        y()
}
_

完全な最小の複数条件カバレッジを得るには、foo(false, whatever)foo(true, false)、およびfoo(true, true)でテストする必要があります。

複数の状態になる可能性のあるオブジェクトがある場合は、制御フローに類似したすべての状態遷移をテストするのが賢明なようです。

より複雑なカバレッジメトリックがいくつかありますが、それらは一般的にここに示されているメトリックに似ています。

これらはホワイトボックステスト方法であり、部分的に自動化できます。単体テストスイートは、選択した任意のメトリックによるhighコードカバレッジを目指している必要がありますが、100%が常に可能であるとは限りません。例外を特定の場所に挿入する必要がある例外処理をテストすることは特に困難です。

機能テスト

次に、機能テストがあります。これは、実装をブラックボックスと見なして、コードが仕様に準拠していることを表明します。このようなテストは、単体テストと統合テストの両方に役立ちます。すべての可能な入力データを使用してテストすることは不可能であるため(たとえば、すべての可能な文字列を使用して文字列の長さをテストする)、入力(および出力)を同等のクラスにグループ化すると便利です-length("foo")が正しい場合、foo("bar")も機能する可能性があります。入力等価クラスと出力等価クラス間の可能な組み合わせごとに、少なくとも1つの代表的な入力が選択され、テストされます。

さらにテストする必要があります

  • エッジケースlength("")foo("x")length(longer_than_INT_MAX)
  • 言語で許可されているが、関数length(null)のコントラクトでは許可されていない値、および
  • ジャンクデータの可能性length("null byte in \x00 the middle")

数値の場合、これは_0, ±1, ±x, MAX, MIN, ±∞, NaN_のテスト、および浮動小数点比較の場合、2つの隣接する浮動小数点のテストを意味します。別の追加として、ランダムなテスト値を同値類から選ぶことができます。デバッグを容易にするために、使用したシードを記録することは価値があります…

非機能テスト:負荷テスト、ストレステスト

一部のソフトウェアには機能以外の要件があり、これらもテストする必要があります。これらには、定義された境界でのテスト(負荷テスト)、およびそれらを超えたテスト(ストレステスト)が含まれます。コンピュータゲームの場合、これは負荷テストで1秒あたりの最小フレーム数をアサートしている可能性があります。予想される2倍のビジターがサーバーに打撃を与えているときの応答時間を観察するために、ウェブサイトはストレステストされるかもしれません。このようなテストは、システム全体だけでなく、単一のエンティティにも関連します。ハッシュテーブルは、100万のエントリでどのように低下​​しますか?

他の種類のテストは、シナリオがシミュレートされるシステム全体のテスト、または開発契約が履行されたことを証明するための受け入れテストです。

非試験方法

レビュー

品質保証に使用できる非テスト手法があります。例としては、ウォークスルー、正式なコードレビュー、ペアプログラミングなどがあります。一部の部品は自動化できますが(例えば、リンターを使用することにより)、これらは一般に時間がかかります。ただし、経験豊富なプログラマによるコードレビューでは、バグが頻繁に発見されるため、自動テストが不可能な設計時に特に役立ちます。

コードレビューが非常に優れているのに、なぜテストを作成するのですか?テストスイートの大きな利点は、それらが(ほとんど)自動的に実行できることであり、regression testに非常に役立ちます。

正式な検証

正式な検証が行われ、証明コードの特定のプロパティ。手作業による検証は、ほとんどの場合、重要な部分に対して実行可能ですが、プログラム全体に対してはそうではありません。証明は、プログラムの正確さについて下限を示します。証明はある程度自動化できます。静的型チェッカー経由。

特定の不変条件は、assertステートメントを使用して明示的にチェックできます。


これらのテクニックはすべてその場にあり、補完的です。 TDDは機能テストを最初に記述しますが、コードが実装されると、カバレッジメトリックによってテストを判断できます。

テスト可能なコードを書くとは、個別にテストできる小さなコードユニット(適切な粒度で単一の責任の原則を持つヘルパー関数)を書くことです。各関数が取る引数が少ないほど良いです。このようなコードは、モックオブジェクトの挿入にも役立ちます。依存性注入を介して。

5
amon

多分「仕様ベースのテスト」もあなたの質問に答えます。これらのテストモジュール(まだ使用していません)を確認してください。選択した単一のデータ値を使用して単体テストを記述するのではなく、テスト値のセットを指定するために、MATHY式を記述する必要があります。

テスト::レクトロテスト

著者が言うように、このPerlモジュールは HaskellのQuick-Check Module に触発されました。このページには他にもリンクがあり、そのうちのいくつかは死んでいます。

4
knb

いくつかの数式が使用されていますが、使用しているソフトウェアテストの種類によって異なります。たとえば、Critical Fault Assumptionは、障害が2つ以上の同時障害の結果であるとはほとんど考えていません。次の方程式は次のとおりです。f = 4n + 1.f=与えられた変数の数(n)+ 1は、すべての変数が公称値をとる定数1の加算です。

数式を必要とする別のタイプのテストは堅牢性テストは、テストプロセスのテストケースの堅牢性または正確性をテストすることです。このテストでは、合法的な入力範囲内の変数(クリーンなテストケース)と入力範囲外の変数(ダーティなテストケース)を入力します。次の数式を使用します:f = 6n + 16nは、各変数が6つの異なる値を想定し、他の値は公称値を想定する必要があることを示します。 * + 1 *は定数1の追加を表します。

数学に基づくアプローチの1つは すべてのペアのテスト です。アイデアは、ほとんどのバグは単一の構成オプションの選択によってアクティブ化され、残りのほとんどは同時に実行される特定のペアのオプションによってアクティブ化されるというものです。したがって、ほとんどは「すべてのペア」をテストすることで検出できます。数学的な説明(一般化)は次のとおりです。

AETGシステム:組み合わせ設計に基づくテストへのアプローチ

(そのような参照はもっとたくさんあります)

2
David Ketcheson