IntelliTest を使用すると、バグを早期に見つけ、テストメンテナンスコストを削減できます。 IntelliTest は、自動化された透過的なテストアプローチを使用して、.NET コードのテストの候補スイートを生成できます。 テスト スイートの生成は、指定した 正確性プロパティ によってさらにガイドできます。 IntelliTest は、テスト対象のコードが進化するにつれて、テスト スイートを自動的に進化させます。
注
IntelliTest は Visual Studio 2026 では非推奨です。 Visual Studio 2022 では、IntelliTest は .NET Framework でのみサポートされており、Visual Studio Enterprise に限定されています。 .NET 6 のサポートは、プレビュー バージョンのみに制限されていました。
注
Visual Studio 2022 では、IntelliTest は .NET Framework でのみサポートされており、Visual Studio Enterprise に限定されています。 .NET 6 のサポートは、プレビュー バージョンのみに制限されていました。
特性評価テスト IntelliTest を使用すると、従来の単体テストスイートの観点からコードの動作を判断できます。 このようなテスト スイートは回帰スイートとして使用でき、レガシコードや未知のコードのリファクタリングに関連する複雑さに取り組むための基礎を形成します。
ガイド付きテスト入力の生成 IntelliTest では、オープン コード分析と制約解決アプローチを使用して、正確なテスト入力値を自動的に生成します。通常、ユーザーの介入を必要としません。 複合オブジェクト型の場合は、ファクトリが自動的に生成されます。 要件に合わせてファクトリを拡張および構成することで、テスト入力の生成をガイドできます。 コード内のアサーションとして指定された正確性プロパティは、テスト入力の生成をさらにガイドするために自動的に使用されます。
IDE 統合 IntelliTest は、Visual Studio IDE に完全に統合されています。 テスト スイートの生成中に収集されたすべての情報 (自動生成された入力、コードからの出力、生成されたテスト ケース、成功または失敗の状態など) は、Visual Studio IDE 内に表示されます。 Visual Studio IDE から離れることなく、コードの修正と IntelliTest の再実行を簡単に繰り返すことができます。 テストは単体テスト プロジェクトとしてソリューションに保存でき、その後、Visual Studio テスト エクスプローラーによって自動的に検出されます。
既存のテスト プラクティスを補完する IntelliTest を使用して、既に従っている可能性がある既存のテスト プラクティスを補完します。
テストする場合:
- プリミティブ データまたはプリミティブ データの配列に対するアルゴリズム:
- パラメーター化された単体テストを記述する
- コンパイラなどの複雑なデータに対するアルゴリズム:
- 最初に IntelliTest でデータの抽象表現を生成し、それをアルゴリズムにフィードします
- IntelliTest でカスタム オブジェクトの作成とデータインバリアントを使用してインスタンスをビルドし、アルゴリズムを呼び出す
- データ コンテナー:
- パラメーター化された単体テストを記述する
- IntelliTest でカスタム オブジェクトの作成とデータインバリアントを使用してインスタンスをビルドし、後でコンテナーのメソッドを呼び出してインバリアントを再確認する
- パラメーター値に応じて、実装のさまざまなメソッドを呼び出すパラメーター 化された単体テスト を記述する
- 既存のコード ベース:
- Visual Studio の IntelliTest ウィザードを使用して、パラメーター化された単体テスト (PUT) のセットを生成して開始する
IntelliTest の Hello World
IntelliTest は、テスト対象のプログラムに関連する入力を検索します。つまり、これを使用して有名な Hello World! 文字列を生成できます。 これは、C# MSTest ベースのテスト プロジェクトを作成し、 Microsoft.Pex.Framework への参照を追加していることを前提としています。 別のテスト フレームワークを使用している場合は、C# クラス ライブラリを作成し、プロジェクトの設定方法に関するテスト フレームワークのドキュメントを参照してください。
次の例では、IntelliTest が必要な文字列を生成するように、パラメーターの名前付き 値 に対して 2 つの制約を作成します。
using System;
using Microsoft.Pex.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public partial class HelloWorldTest {
[PexMethod]
public void HelloWorld([PexAssumeNotNull]string value) {
if (value.StartsWith("Hello")
&& value.EndsWith("World!")
&& value.Contains(" "))
throw new Exception("found it!");
}
}
コンパイルして実行すると、IntelliTest は次のような一連のテストを生成します。
- ""
- "\0\0\0\0\0"
- "Hello"
- "\0\0\0\0\0\0"
- こんにちは\0
- こんにちは\0\0
- "Hello\0World!"
- "Hello World!"
注
ビルドの問題については、Microsoft.VisualStudio.TestPlatform.TestFramework および Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions 参照を Microsoft.VisualStudio.QualityTools.UnitTestFramework への参照に置き換えてみてください。
IntelliTest を使用した単体テストの生成を読み、生成されたテストが保存される場所を理解します。 生成されたテスト コードには、次のコードのようなテストが含まれている必要があります。
[TestMethod]
[PexGeneratedBy(typeof(global::HelloWorldTest))]
[PexRaisedException(typeof(Exception))]
public void HelloWorldThrowsException167()
{
this.HelloWorld("Hello World!");
}
それは簡単です!
その他のリソース:
重要な属性
- PexClass はPUT を含む型をマークします
- PexMethod が PUT をマークする
- PexAssumeNotNull は null 以外のパラメーターをマークします
using Microsoft.Pex.Framework;
[..., PexClass(typeof(Foo))]
public partial class FooTest {
[PexMethod]
public void Bar([PexAssumeNotNull]Foo target, int i) {
target.Bar(i);
}
}
- PexAssemblyUnderTest がテスト プロジェクトをプロジェクトにバインドする
- PexInstrumentAssembly は、インストルメント化するアセンブリを指定します
[assembly: PexAssemblyUnderTest("MyAssembly")] // also instruments "MyAssembly"
[assembly: PexInstrumentAssembly("Lib")]
重要な静的ヘルパー クラス
- PexAssume が 前提条件を評価する (入力フィルター処理)
- PexAssert がアサーションを評価する
- PexChoose によって新しい選択肢が生成される (追加入力)
- PexObserve は、生成されたテストにライブ値をログに記録します
[PexMethod]
void StaticHelpers(Foo target) {
PexAssume.IsNotNull(target);
int i = PexChoose.Value<int>("i");
string result = target.Bar(i);
PexObserve.ValueForViewing<string>("result", result);
PexAssert.IsNotNull(result);
}
制限事項
このセクションでは、IntelliTest の制限事項について説明します。
非決定的主義
IntelliTest は、分析されたプログラムが決定論的であると想定しています。 そうでない場合、IntelliTest は探索の制限に達するまで繰り返します。
IntelliTest では、IntelliTest で制御できない入力に依存している場合、プログラムは非抑制的であると見なされます。
IntelliTest は、 パラメーター化された単体テスト に提供され、 PexChoose から取得された入力を制御します。 その意味では、アンマネージド コードまたはインストルメント化されていないコードの呼び出しの結果もインストルメント化されたプログラムへの "入力" と見なされますが、IntelliTest では制御できません。 プログラムの制御フローがこれらの外部ソースからの特定の値に依存している場合、IntelliTest は以前に発見された領域にプログラムを "誘導" することはできません。
さらに、プログラムを再実行するときに外部ソースからの値が変更された場合、プログラムは非抑制的であると見なされます。 このような場合、IntelliTest はプログラムの実行を制御できなくなり、その検索は非効率的になります。
これがいつ起こるかは明らかでない場合があります。 次の例を考えてみましょう。
- GetHashCode() メソッドの結果はアンマネージ コードによって提供され、予測できません。
- System.Random クラスは、現在のシステム時刻を使用して、真にランダムな値を提供します。
- System.DateTime クラスは、IntelliTest の制御下にない現在の時刻を提供します。
Concurrency
IntelliTest では、マルチスレッド プログラムは処理されません。
ネイティブ コード
IntelliTest は、 P/Invoke を介して呼び出される x86 命令などのネイティブ コードを理解していません。 このような呼び出しを制約 ソルバーに渡すことができる制約に変換する方法はわかりません。 .NET コードの場合でも、インストルメント化するコードのみを分析できます。 IntelliTest では、リフレクション ライブラリを含む mscorlib の特定の部分をインストルメント化できません。 DynamicMethod はインストルメント化できません。
推奨される回避策は、このようなメソッドが動的アセンブリ内の型にあるテスト モードを使用することです。 ただし、一部のメソッドがインストルメント化されていない場合でも、IntelliTestはインストルメント化されたコードをできるだけ多くカバーしようとします。
Platform
IntelliTest は x86、32 ビット .NET Framework でのみサポートされています。
Language
原則として、IntelliTest は任意の .NET 言語で記述された任意の .NET プログラムを分析できます。 ただし、Visual Studio では C# のみがサポートされます。
シンボリック推論
IntelliTest では、自動 制約ソルバー を使用して、テストとテスト対象のプログラムに関連する値を決定します。 ただし、制約ソルバーの機能は常に制限されます。
スタック トレースが正しくない
IntelliTest はインストルメント化された各メソッドで例外をキャッチして "再スロー" するため、スタック トレースの行番号は正しくありません。 これは、"再スロー" 命令の設計による制限です。