従来の単体テストでは、テストはいくつかの要素で構成されています。
- メソッド呼び出しのシーケンス
- メソッドが呼び出される引数。引数はテスト入力です
- 一連のアサーションを指定して、テスト対象アプリケーションの意図された動作を検証 する
テスト構造の例を次に示します。
[Test]
void MyTest() {
// data
ArrayList a = new ArrayList();
// method sequence
a.Add(5);
// assertions
Assert.IsTrue(a.Count==1);
Assert.AreEqual(a[0], 5);
}
IntelliTest では、多くの場合、メソッド呼び出しとアサーションのシーケンスを提供する、より一般的な パラメーター化単体テストの関連する引数値を自動的に決定できます。
テスト ジェネレーター
IntelliTest では、テスト対象の実装の一連のメソッドを選択して実行し、派生データに対するアサーションをチェックしながらメソッドの入力を生成することで、テスト ケースが生成されます。
パラメーター化された単体テストでは、本体内のメソッド呼び出しのシーケンスを直接示します。
IntelliTest でオブジェクトを構築する必要がある場合、コンストラクターとファクトリ メソッドの呼び出しは、必要に応じてシーケンスに自動的に追加されます。
パラメーター化された単体テスト
パラメーター化された単体テスト (PUT) は、パラメーターを受け取るテストです。 通常は閉じられているメソッドである従来の単体テストとは異なり、PUT はパラメーターのセットを受け取ります。 それは簡単ですか? はい - そこから、IntelliTest は、テストから到達可能なコードを完全にカバーする入力の (最小限の) セットを生成しようとします。
PUT は、MSTest (または NUnit、xUnit) と同様の方法で PexMethod カスタム属性を使用して定義されます。 PUT は、 PexClass でタグ付けされたクラスで論理的にグループ化されたインスタンス メソッドです。 次の例は、 MyPexTest クラスに格納されている単純な PUT を示しています。
[PexMethod]
void ReplaceFirstChar(string target, char c) {
string result = StringHelper.ReplaceFirstChar(target, c);
Assert.AreEqual(result[0], c);
}
ReplaceFirstChar は、文字列の最初の文字を置き換えるメソッドです。
class StringHelper {
static string ReplaceFirstChar(string target, char c) {
if (target == null) throw new ArgumentNullException();
if (target.Length == 0) throw new ArgumentOutOfRangeException();
return c + target.Substring(1);
}
}
このテストから、IntelliTest は、テストされたコードの多くの実行パスをカバーする PUT の入力を自動的に 生成 できます。 異なる実行パスをカバーする各入力は、単体テストとして "シリアル化" されます。
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
void ReplaceFirstChar0() {
this.ReplaceFirstChar(null, 0);
}
...
[TestMethod]
void ReplaceFirstChar10() {
this.ReplaceFirstChar("a", 'c');
}
ジェネリック パラメーター化された単体テスト
パラメーター化された単体テストは、ジェネリック メソッドにすることができます。 この場合、ユーザーは PexGenericArguments を使用してメソッドをインスタンス化するために使用する型を指定する必要があります。
[PexClass]
public partial class ListTest {
[PexMethod]
[PexGenericArguments(typeof(int))]
[PexGenericArguments(typeof(object))]
public void AddItem<T>(List<T> list, T value)
{ ... }
}
例外の許可
IntelliTest には、予期される例外と予期しない例外への例外のトリアージに役立つさまざまな検証属性が用意されています。
予期される例外では 、ExpectedException(typeof(xxx)) などの適切な注釈を持つ負のテスト ケースが生成されますが、予期しない例外では失敗したテスト ケースが生成されます。
[PexMethod, PexAllowedException(typeof(ArgumentNullException))]
void SomeTest() {...}
バリデーターは次のとおりです。
- PexAllowedException: どこからでも特定の例外の種類を許可します
- PexAllowedExceptionFromAssembly: 指定したアセンブリから特定の例外の種類を許可します
- PexAllowedExceptionFromType: 指定した型から特定の例外の種類を許可します
- PexAllowedExceptionFromTypeUnderTest: テスト対象の型から特定の例外の種類を許可します
内部型のテスト
IntelliTest は、内部型がアクセス可能である限り、内部型を「テスト」できます。 IntelliTest で型を確認するには、Visual Studio IntelliTest ウィザードによって次の属性が製品またはテスト プロジェクトに追加されます。
[assembly: InternalsVisibleTo("Microsoft.Pex, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
前提条件とアサーション
ユーザーは、前提条件とアサーションを使用して、テストに関 する前提条件 (前提条件) と 事後条件 (アサーション) を表現できます。 IntelliTest がパラメーター値のセットを生成し、コードを "探索" すると、テストの前提に違反する可能性があります。 その場合、そのパスのテストは生成されませんが、暗黙的に無視されます。
アサーションは通常の単体テスト フレームワークでよく知られている概念であるため、IntelliTest は、サポートされている各テスト フレームワークによって提供される組み込みの Assert クラスを既に "理解" しています。 ただし、ほとんどのフレームワークでは Assume クラスは提供されません。 その場合、IntelliTest は PexAssume クラスを提供します 。 既存のテスト フレームワークを使用しない場合、IntelliTest には PexAssert クラスもあります。
[PexMethod]
public void Test1(object o) {
// precondition: o should not be null
PexAssume.IsNotNull(o);
...
}
特に、null 以外の前提は、カスタム属性としてエンコードできます。
[PexMethod]
public void Test2([PexAssumeNotNull] object o)
// precondition: o should not be null
{
...
}
前提条件
メソッドの前提条件は、メソッドが成功する条件を表します。
通常、前提条件は、パラメーターとオブジェクトの状態を確認し、違反した場合は ArgumentException または InvalidOperationException をスローすることによって適用されます。
IntelliTest では、 パラメーター化された単体テスト の前提条件が PexAssume で表されます。
事後条件
メソッドの事後条件は、その前提条件が最初に有効であったと仮定して、メソッドの実行中と実行後に保持する必要がある条件を表します。
通常、事後条件は Assert メソッドの呼び出しによって適用されます。
IntelliTest では、 パラメーター化された単体テスト の事後条件が PexAssert で表されます。
テスト不合格
生成されたテスト ケースが失敗するタイミング
構成されたパス境界内で終了しない場合、TestExcludePathBoundsExceeded オプションが設定されていない限り、エラーと見なされます。
テストが PexAssumeFailedException をスローすると、成功します。 ただし、TestEmissionFilter が All に設定されていない限り、通常は除外されます
テストが アサーションに違反している場合。たとえば、単体テスト フレームワークのアサーション違反例外をスローすると、失敗します。
上記のいずれにも決定が生じない場合、例外がスローされない場合にのみ、テストは成功します。 アサーション違反は、例外と同じ方法で処理されます。
セットアップと設定解除
IntelliTest では、テスト フレームワークとの統合の一環として、セットアップメソッドと破棄メソッドの検出と実行がサポートされています。
例
using Microsoft.Pex.Framework;
using NUnit.Framework;
namespace MyTests
{
[PexClass]
[TestFixture]
public partial class MyTestClass
{
[SetUp]
public void Init()
{
// monitored
}
[PexMethod]
public void MyTest(int i)
{
}
[TearDown]
public void Dispose()
{
// monitored
}
}
}
詳細については、次を参照してください。
フィードバックをお寄せください。
開発者コミュニティにアイデアや機能のリクエストを投稿します。