IntelliTest は、プログラム内の分岐条件を分析することによって、 パラメーター化された単体テスト の入力を生成します。 テスト入力は、プログラムの新しい分岐動作をトリガーできるかどうかに基づいて選択されます。 分析は増分プロセスです。 正式なテスト入力パラメーターq: I -> {true, false}に対して述語Iを調整します。
q は、IntelliTest で既に観察されている動作のセットを表します。 最初は、 q := false、まだ何も観察されていないためです。
ループの手順は次のとおりです。
IntelliTest は、制約ソルバーを使用して、入力
iがq(i)=falseになるように決定します。 構築によって、入力iは前に見たことのない実行パスを受け取ります。 最初は、実行パスがまだ検出されていないため、i任意の入力を指定できることを意味します。IntelliTest は、選択した入力
iでテストを実行し、テストの実行とテスト対象のプログラムを監視します。実行中、プログラムは、プログラムのすべての条件付き分岐によって決定される特定のパスを受け取ります。 実行を決定するすべての条件のセットは パス条件と呼ばれ、仮入力パラメーターに対する述語
p: I -> {true, false}として記述されます。 IntelliTest は、この述語の表現を計算します。IntelliTest は
q := (q or p)を設定します。 つまり、pで表されるパスを見たという事実を記録します。手順 1 に進みます。
IntelliTest の 制約ソルバー は、.NET プログラムに表示されるすべての型の値を処理できます。
IntelliTest は、指定された前提条件に違反する入力を除外します。
即時入力 ( パラメーター化された単体テストの引数) に加えて、テストは PexChoose 静的クラスからさらに入力値を描画できます。 選択肢によって、 パラメーター化されたモックの動作も決まります。
制約ソルバー
IntelliTest では、制約ソルバーを使用して、テストの関連する入力値とテスト対象のプログラムを決定します。
IntelliTest では、 Z3 制約ソルバーが使用されます。
動的コード カバレッジ
ランタイム監視の副作用として、IntelliTest は動的なコード カバレッジ データを収集します。 これは 動的 と呼ばれます。IntelliTest では実行されたコードについてのみ認識されるため、他のカバレッジ ツールと同じ方法でカバレッジの絶対値を指定することはできません。
たとえば、IntelliTest が動的カバレッジを 5/10 の基本ブロックとして報告する場合、これは 10 個のうち 5 ブロックがカバーされたことを意味します。ここで、(テスト対象アセンブリに存在するすべてのメソッドではなく) 分析によってこれまでに到達したすべてのメソッドのブロックの合計数は 10 個です。 分析が進むにつれて、新たな到達可能なメソッドが検出されると、分子 (この例では 5) と分母 (10) の両方が増加します。
整数と浮動小数点数
IntelliTest の 制約ソルバー は、テストとテスト対象のプログラムに対して異なる実行パスをトリガーするために、 バイト、 int、 float などのプリミティブ型のテスト入力値を決定します。
オブジェクト
IntelliTest では 、既存の .NET クラスのインスタンスを作成することも、IntelliTest を使用して、特定のインターフェイスを実装し、使用状況に応じてさまざまな方法で動作する モック オブジェクト を自動的に作成することもできます。
既存のクラスをインスタンス化する
何がそんなに問題ですか。
IntelliTest は、テストの実行時に実行された命令と、テスト対象のプログラムを監視します。 特に、フィールドへのすべてのアクセスを監視します。 次に、 制約ソルバー を使用して、オブジェクトとそのフィールド値を含む新しいテスト入力を決定し、テスト対象のテストとプログラムが他の興味深い方法で動作するようにします。
つまり、IntelliTest は特定の型のオブジェクトを作成し、そのフィールド値を設定する必要があります。 クラスが表示され、 既定 のコンストラクターが 表示 されている場合、IntelliTest はクラスのインスタンスを作成できます。 クラスのすべてのフィールドが 表示されている場合、IntelliTest はフィールドを自動的に設定できます。
型が表示されない場合、またはフィールドが 表示されない場合、IntelliTest では、最大限のコード カバレッジを実現するために、オブジェクトを作成し、それらを興味深い状態にするのに役立つ必要があります。 IntelliTest ではリフレクションを使用して任意の方法でインスタンスを作成および初期化できますが、通常は、通常、プログラムの実行中にオブジェクトが発生しない状態になる可能性があるため、これは望ましくありません。 代わりに、IntelliTest はユーザーからのヒントに依存します。
可視性
.NET には、型、メソッド、フィールド、およびその他のメンバーを プライベート、 パブリック、 内部など、複雑な可視性モデルがあります。
IntelliTest は、テストを生成するときに、生成されたテストのコンテキスト内から .NET 可視性ルールに関して有効なアクション (コンストラクター、メソッド、設定フィールドの呼び出しなど) のみを実行しようとします。
規則は次のとおりです。
内部メンバーの可視性
- IntelliTest では、生成されたテストが、外側の PexClass に表示されていた内部メンバーにアクセスできるものとします。 .NET には、内部メンバーの可視性を他のアセンブリに拡張するための InternalsVisibleToAttribute があります。
PexClass のプライベートメンバーとファミリメンバー (C#で保護) の可視性
パブリック メンバーの可視性
- IntelliTest では、 PexClass のコンテキストで表示されるすべてのエクスポートされたメンバーを使用できるものとします。
パラメーター化されたモック
インターフェイス型のパラメーターを持つメソッドをテストする方法 またはシールドされていないクラスですか? IntelliTest は、このメソッドが呼び出されたときに後で使用される実装を認識しません。 テスト時に実際の実装も利用できない可能性があります。
従来の答えは、明示的な動作で モックオブジェクト を使用することです。
モック オブジェクトはインターフェイスを実装します (または、シールされていないクラスを拡張します)。 実際の実装ではなく、モック オブジェクトを使用してテストを実行できるショートカットのみを表します。 その動作は、使用される各テスト ケースの一部として手動で定義されます。 モック オブジェクトとその期待される動作を簡単に定義できるツールが多数存在しますが、この動作は引き続き手動で定義する必要があります。
モック オブジェクトでハードコーディングされた値の代わりに、IntelliTest で値を生成できます。 パラメーター化された単体テストを有効にするのと同様に、IntelliTest ではパラメーター化されたモックも有効になります。
パラメーター化されたモックには、次の 2 つの異なる実行モードがあります。
- 選択: コードを探索する場合、パラメーター化されたモックは追加のテスト入力のソースであり、IntelliTest は興味深い値の選択を試みます
- 再生: 以前に生成されたテストを実行すると、パラメーター化されたモックは、動作 (つまり、定義済みの動作) を持つスタブのように動作します。
パラメーター化されたモックの値を取得するには 、PexChoose を使用します。
構造体
構造体値に関する IntelliTest の推論は、オブジェクトの処理方法と似ています。
配列と文字列
IntelliTest は、テストの実行中に実行された命令と、テスト対象のプログラムを監視します。 特に、プログラムが文字列または配列の長さ (および多次元配列の下限と長さ) に依存するタイミングを観察します。 また、プログラムが文字列または配列のさまざまな要素を使用する方法も確認します。 次に、 制約ソルバー を使用して、テストとテスト対象のプログラムが興味深い方法で動作する可能性がある長さと要素の値を決定します。
IntelliTest は、興味深いプログラムの動作をトリガーするために必要な配列と文字列のサイズを最小限に抑えようとします。
追加の入力を取得する
PexChoose 静的クラスは、テストへの追加の入力を取得するために使用でき、パラメーター化されたモックを実装するために使用できます。
フィードバックをお寄せください。
開発者コミュニティにアイデアや機能のリクエストを投稿します。