■例外のテスト
メソッドによっては、想定していない値や不正な値が入力されたときに例外を返すものも存在する。そのようなメソッドをテストするための機能も提供されている。
この場合には、テスト・メソッドに対して、ExpectedException属性を用いて期待する例外(=例外クラスの型)を指定しておき、メソッドでその例外が発生すれば、テストが成功したことになる。
以下の例は、誕生日よりも前の日付が渡されたときに、InvalidOperationException例外がスローされるのをテストしている。
/// <summary>
///GetAge のテスト
///</summary>
[TestMethod(), ExpectedException(typeof(System.InvalidOperationException))]
public void GetAgeTest4()
{
ClassLibrary4.Class1 target = new ClassLibrary4.Class1();
System.DateTime birthday = new System.DateTime(1976, 12, 14);
System.DateTime targetDate = new System.DateTime(1970, 1, 1);
int expected = 0;
int actual;
actual = target.GetAge(birthday, targetDate);
}
■時間制約付きのテスト
処理を一定時間内に終わらせる必要のあるメソッドのテストも可能だ。
この場合、[テスト ビュー]ウィンドウで対象のテストを選択してから、[プロパティ]ウィンドウの「タイムアウト」に、テスト処理のタイムアウト値を指定する。
このようにプロパティを設定すると、そのテスト・メソッドの属性が以下のように変更される。
[Timeout(5000), TestMethod()]
ここでは処理が5秒以上かかるように、メソッドにウェイトを指定してみる。
public int TimeOut()
{
System.Threading.Thread.Sleep(6000);
return 0;
}
このテストを実施すると、次のような結果になる。
恐らく最初からメソッドの処理時間が指定されるケースは少ないと思うが、パフォーマンス・チューニングなどで一定以上の速度にする必要があるときに便利だ。
■グループ単位のテスト
ソリューションに含まれるすべてのテストを実施する以外にも、ある論理単位でテストをグループ化してテストを実施することができる。
[テスト ビュー]ウィンドウで「グループ化」のドロップダウンを選択することで、テストのグループ化の方法の選択が可能だ。以下の画面は、「説明」の内容によってグループ化した例である(「説明」の設定については後述)。
グループ化には、「クラス名」や「プロジェクト」(ソリューションに複数のテスト・プロジェクトが含まれている場合)など、特に何の設定もなく有効なものもあるが、上の画面のように「説明」という論理的な項目でのグループ化も可能である。論理的なグループには、「所有者」「説明」「優先順位」がある。これらはそれぞれ、テストのプロパティで指定できる。
テストにグループ化のためのプロパティを指定した場合、テスト・メソッドには以下のような属性が追加される。
[Owner("テスト担当者A"), Priority(30), Description("年齢計算のテスト"), TestMethod()]
このように、論理的にグループ化されたテスト・グループの単位でテストを実施できる。グループでのテストを実施するには、[テスト ビュー]ウィンドウでテスト・グループが選択された状態で、([テスト ビュー]ウィンドウの)ツールバー部分にある[選択範囲の実行]または、[選択範囲のデバッグ]を実施すればよい。
■テストを一時的に無効にする
テスト・コードを記述したが、一時的にテストを無効にしたい場合、[テスト ビュー]ウィンドウで対象のテストを選択して[プロパティ]ウィンドウの「有効なテスト」を「False」にすればよい。
これによってテスト・メソッドにはIgnore属性が追加される。
[TestMethod()]
[Ignore]
このように複数のテストを実施しても、無効に設定されているテストだけは実施されないように設定できる。
メソッドの処理結果を判定するためのAssertクラスには、値を比較するための評価メソッドが複数提供されている。Assertは「(テスト結果が)こうあるべき」を宣言するための構文ととらえることができ、例えば、ここまで使ってきたAreEqualメソッドは、「同じであるべき」と読み替えられる。
Assertクラスに含まれる評価メソッドは、以下のように基本的に肯定系と否定系がセットで用意されている。
肯定系 | 否定系 | 説明 |
---|---|---|
AreEqual | AreNotEqual | 2つの値が同一である(AreEqual)、または、同一ではない(AreNotEqual)ことを評価する |
AreSame | AreNotSame | 2つのオブジェクトが同じインスタンスである(AreSame)、または、違うインスタンス(AreNotSame)であることを評価する |
IsTrue | IsFalse | Boolean値がTrueである(IsTrue)、または、Falseである(IsFalse)ことを評価する |
IsInstanceOfType | IsNotInstanceOfType | クラスのインスタンスがある型のインスタンスである(IsInstanceOfType)、または、別なクラスのインスタンス(IsNotInstanceOfType)であることを評価する |
IsNull | IsNotNull | クラスのインスタンスがNullである(IsNull)、または、Null以外である(IsNotNull)ことを評価する |
−−−
メソッド名 | 説明 |
---|---|
Fail | テストを失敗させる。コードで評価した結果、失敗だった場合に使用する |
Assertクラスの評価メソッド |
文字列の評価にはStringAssertクラスが用意されている。StringAssertクラスに含まれる評価メソッドは以下のとおりだ。
肯定系 | 否定系 | 説明 |
---|---|---|
Matches | DoesNotMatch | 文字列が正規表現と一致する(Matches)、または、一致しない(DoesNotMatch)ことを評価する |
−−−
メソッド名 | 説明 |
---|---|
Contains | 文字列に特定の文字列が含まれていることを評価する |
StartsWith | 文字列が特定の文字列から始まっていることを評価する |
EndsWith | 文字列が特定の文字列で終わっていることを評価する |
StringAssertクラスの評価メソッド |
もう1つ、コレクションを評価するためのCollectionAssertクラスも提供されている。CollectionAssertクラスに含まれる評価メソッドは以下のとおりだ。
肯定系 | 否定形 | 説明 |
---|---|---|
AreEqual | AreNotEqual | コレクションに含まれるアイテムが順番も含めてすべて一致すること(AreEqual)、または、完全には一致しない(AreNotEqual)ことを評価する |
AreEquivalent | AreNotEquivalent | コレクションに含まれるアイテムの順番に関係なくすべて一致すること(AreEquivalent)、または、完全には一致しないこと(AreNotEquivalent)を評価する |
Contains | DoesNotContains | コレクションに特定のアイテムが含まれていること(Contains)、または、含まれていないこと(DoesNotContains)を評価する |
IsSubsetOf | IsNotSubsetOf | コレクションが特定のコレクションのサブセットであること(IsSubsetOf)、または、サブセットではないこと(IsNotSubsetOf)を評価する |
−−−
メソッド名 | 説明 |
---|---|
AllItemsAreNotNull | コレクションにnullのアイテムが含まれないことを評価する |
AllItemsAreInstanceOfType | コレクションに含まれるメソッドがすべて特定のクラスのインスタンスであることを評価する |
AllItemsAreUnique | コレクションに含まれるアイテムがすべてユニークであることを評価する |
CollectionAssertクラスの評価メソッド |
このように、メソッドの結果を評価するために必要になるであろうメソッドが各種準備されている。もし、提供されているメソッドで評価しきれない場合は、失敗した場合にAssertクラスのFailメソッドを呼び出すようなコードを独自に記述すればよい。
今回はVS 2008 Professional Editionで実施可能な単体テスト機能を網羅的に解説した。次回ではVS 2008を使って簡単なテスト駆動開発を実践してみる。また、NUnitとの互換性についても確認する。
Copyright© Digital Advantage Corp. All Rights Reserved.