MbUnit3.1の機能拡張を試してみた

.NET用のテストフレームワークの一つ「MbUnit」。
バージョン3.1での機能拡張を試してみました。
Gallio/MbUnitについてはコチラ


MbUnitではユーザ独自に拡張した属性を使用することで
継承やテストクラスごとに(NUnitでもお馴染な)SetUp、TearDownメソッドで
共通処理の呼び出しを書くなどしなくても
テスト共通の前処理、後処理等を実行することができるようになります。


手探りでの実行結果になりますが、備忘録代わりに。

  • 1.拡張用の属性クラスを作成
    • 参照設定
      Gallioインストール後、参照設定の「NET」タブから下記dllを追加)
    • 使用クラス
      • MbUnit.Framework.TestDecoratorAttribute
        「Execute」などの各メソッドをoverrideして拡張したい処理を記述します。


///
/// MbUnit3拡張クラス
///

public class CustomTestAttribute : MbUnit.Framework.TestDecoratorAttribute {
private readonly string TYPE_NAME;
public CustomTestAttribute() {
TYPE_NAME = GetType().Name;
}

///


/// テストメソッド実行時に呼び出される
///

///
/// テストクラスのインスタンス等、各種テスト情報を保持
///
protected override void Execute(Gallio.Framework.Pattern.PatternTestInstanceState testInstanceState) {
Console.WriteLine("* [Start]:{0}.Execute, TestInstance={1}", TYPE_NAME,
testInstanceState.FixtureInstance == null ? "null" : testInstanceState.FixtureInstance);

base.Execute(testInstanceState); // テストメソッドの呼び出し

Console.WriteLine("* [End ]:{0}.Execute", TYPE_NAME);
}

// SetUp,TearDown,Initializeメソッドも同様に拡張(長くなるので省略)
}

  • 2.拡張した属性をテストクラス、テストメソッドに適用する


[TestFixture]
public class SampleTest {
private readonly string TO_STRING_MESSAGE;
private readonly string TYPE_NAME;

public SampleTest() {
TYPE_NAME = GetType().Name;
TO_STRING_MESSAGE = "☆SampleTest#ToString Hoge";
}

// =========================================================================

///


/// MbUnit3拡張属性を使用したテストメソッド1
/// ※「CustomTestAttribute」を「TestAttribute」の後ろに指定する
///

[Test, CustomTest]
public virtual void TestExecuteTest() {
Console.WriteLine("○{0}.TestExecuteTestが呼び出されました。", TYPE_NAME);
}

///


/// MbUnit3拡張属性を使用したテストメソッド2
///

[Test, CustomTest]
public void TestExecuteTest2() {
Console.WriteLine("○{0}.TestExecuteTest2が呼び出されました。", TYPE_NAME);
}

    // =========================================================================

///


/// 拡張していないテストメソッド
///

[Test]
public void NoCustomTest() {
Console.WriteLine("○{0}.NoCustomTestが呼び出されました。", TYPE_NAME);
}

///


/// テストクラス初期化処理
///

[FixtureInitializer]
public void Initialize() {
Console.WriteLine("○{0}.Initalizeが呼び出されました。",TYPE_NAME);
}

///


/// テストクラスセットアップ処理
///

[FixtureSetUp]
public void FixtureSetUp() {
Console.WriteLine("○{0}.FixtureSetUpが呼び出されました。", TYPE_NAME);
}

///


/// テストクラス終了処理
///

[FixtureTearDown]
public void FixtureTearDown() {
Console.WriteLine("○{0}.FixtureTearDownが呼び出されました。", TYPE_NAME);
}

///


/// テストメソッドセットアップ処理
///

[SetUp]
public void SetUp() {
Console.WriteLine("○{0}.SetUpが呼び出されました。", TYPE_NAME);
}

///


/// テストメソッド終了処理
///

[TearDown]
public void TearDown() {
Console.WriteLine("○{0}.TearDownが呼び出されました。", TYPE_NAME);
}

///


/// インスタンス確認のために拡張
///

///
public override string ToString() {
return TO_STRING_MESSAGE;
}
}
上記テストをGallio上で実行すると下の画像のような結果になります。

枠で囲んだ部分を見ると、SampleTestのSetUp、TearDown、テストメソッドの処理を
CustomTestAttributeのSetUp、TearDown、Executeの中から呼び出せていることが
確認できます。
(Initializeの処理もSetUpより更に前に呼び出されています)


また、拡張属性はテストクラスに対しても適用可能です。

[TestFixture, CustomTest]
public class SampleTest {
// 中身はそのまま
}
実行結果は下記の通りになります。

SampleTestのFixtureInitializer、FixtureSetUp、FixtureTearDownの処理を
CustomTestAttributeのInitialize、SetUp、TearDownの中から同様に
呼び出されていることが確認できます。