最後にテストクラスのメソッドが呼び出される順番を見てみましょう。

Fixtureの実装

xUnit.NET ではテストメソッドを実行する度にインスタンスが再作成されます。メソッドごとにインスタンス変数が初期化されるため、テストメソッド間で共有したい情報があればFixtureを使用します。ここではFixtureに数値を保持するCountというプロパティを用意しています。

なお、NUnitではFixtureとテストクラスは似たような意味で使われていましたが、xUnit.NET ではテストクラスを補助するクラスという意味合いで使用されます。

using System;
using System.Diagnostics;

namespace SampleLibTest
{
public class MyFixture : IDisposable
{
    //数を保持するプロパティ
    public int Count { get; set; }

    //テストクラス開始時の処理
    //テストクラスの初期化時に1回だけ呼ばれる
    public MyFixture()
    {
    Debug.WriteLine("{0}:Fixture:コンストラクタ",++Count);
    }

    //テストクラス終了時の処理
    //テストクラスのメソッドがすべて終わった後に1回だけ呼ばれる
    public void Dispose()
    {
    Debug.WriteLine("{0}:Fixture:Dispose", ++Count);
    }
}
}

テストクラスの状態を保持するFixtureクラス

Fixtureには「状態を保持するプロパティ」「テストクラスの初期処理」「テストクラスの終処理」の3つを記述できます。NUnitではTestFixtureSetUp属性(VSTestではClassInitialize属性)を付与してテストクラスの初期処理を行っていましたが、xUnit.NET ではFixtureのコンストラクタに初期処理を記述します。

Fixtureを使用する例としては、データベースのコネクションをプロパティに保持し、コンストラクタでデータベースへの接続、Disposeメソッドでデータベースの切断するシナリオなどが考えられます。

Fixtureを使用するテストクラス

続けて、Fixtureを使用するテストクラスを見てみましょう。Fixtureを用いる際は、IUseFixture<T>インタフェースを実装します。この時、SetFixtureメソッドでFixtureの情報をインスタンス変数にセットするように実装します。これによって、テストメソッドからFixtureを自由に使えるようになります。

using System;
using System.Diagnostics;
using Xunit;

namespace SampleLibTest
{
public class LifecycleDemo : IUseFixture<MyFixture>, IDisposable
{
    //インスタンス変数はテストメソッド毎に初期化される
    private MyFixture _fixture;

    //コンストラクタ(テストメソッド前に呼ばれる)
    public LifecycleDemo()
    {
    //_fixtureは使用できない
    Debug.WriteLine("テストクラス:コンストラクタ");
    }

    //フィクスチャの準備(テストメソッド前に呼ばれる)
    public void SetFixture(MyFixture fixture)
    {
    _fixture = fixture;
    Debug.WriteLine("{0}:SetFixture", ++_fixture.Count);
    }

    //終了時(テストメソッド後に呼ばれる)
    public void Dispose()
    {
    Debug.WriteLine("{0}:テストクラス:Dispose", ++_fixture.Count);
    }

    //テストメソッドX
    [Fact]
    public void テストメソッドX()
    {
    Debug.WriteLine("{0}:テストメソッドX", ++_fixture.Count);
    }

    //テストメソッドY
    [Fact]
    public void テストメソッドY()
    {
    Debug.WriteLine("{0}:テストメソッドY", ++_fixture.Count);
    }

}
}

Fixtureを使用するテストクラスの実装

NUnitではSetUp属性(VSTestではTestInitialize属性)を付与して、テストメソッドの初期処理を記述していましたが、xUnit.NET では、テストクラスのコンストラクタに記述します。このテストコードを実行すると、次の内容が出力されます。

1:Fixture:コンストラクタ
テストクラス:コンストラクタ
2:SetFixture
3:テストメソッドY
4:テストクラス:Dispose
テストクラス:コンストラクタ
5:SetFixture
6:テストメソッドX
7:テストクラス:Dispose
8:Fixture:Dispose

テストクラスの出力結果

重要な注意点として、xUnit.NETではテストメソッドはランダムに実行されます。このコードでは、テストメソッドXが先に呼ばれることもあれば、テストメソッドYが先に呼ばれることもあります。これを不思議に感じるもしれませんが、この制約によってテストメソッドが他のテストメソッドに依存してしまうことが回避されています。

最後に各メソッドが呼び出される順番を整理します。

  1. Fixtureのコンストラクタ
  2. コンストラクタ→SetFixture→テストメソッド→Dispose(これをテストメソッドの回数繰り返す)
  3. FixutreのDispose

以上、xUnit.NETのインストールから実際にテストを実行するまでの手順について紹介してきました。CodePlexには面白いサンプルの他、NUnit、MbUnit、VSTestとの比較ページなどもありますので、興味を持たれた方は参考にしてみてはいかがでしょうか。