6

私は xUnit.NET フレームワークの大ファンです。軽く、シンプルで、クリーンで、拡張可能だと思います。

今、私は次のようなクラスを持っているとしましょう:

public class AdditionSpecification
{
  static int result;

  public void Because()
  {
    result = 2 + 2;
  }

  public void Result_is_non_zero()
  {
    Assert.True(result <> 0);
  }

  public void Result_is_correct()
  {
    Assert.Equal(4, result);
  }
}

上記のテスト クラスを使用して、xUnit.NET に 2 つのテスト ケースを表示させ、各テスト ケースの前に Because() メソッドを実行させたいと考えています。

私のクラスまたはメソッド名、このテスト/仕様の構造、xUnit.NET フレームワーク、または BDD に関する問題はさておき、ここに私の質問があります。

各ターゲット テスト メソッドで [Fact] のようなカスタム属性を使用せずに、このクラスからテスト メソッドを識別して実行する方法をカスタマイズしたいことを xUnit.NET に伝えるにはどうすればよいですか?

実行前と実行後に各テスト メソッドをカスタムで装飾するために、BeforeAfterAttribute から派生できることがわかっています。クラスレベルでこれを行うにはどうすればよいですか? カスタム ランナーを作成する必要がありますか?

4

2 に答える 2

10

したがって、私はITestClassCommand.EnumerateTestMethods()メソッドを探していたことがわかりました。

  1. デフォルトのxUnit.NETテストランナーは、テストアセンブリ内のすべてのクラスを反復処理します。
  2. それぞれについて、RunWithAttributeをチェックします。これは、テストを含むメソッドを識別するために使用されるITestClassCommand実装をオーバーライドするチャンスです。(RunWithNUnitは良い例です)
  3. ITestClassCommand.EnumerateTestMethods()は、テストクラスを処理し、テストメソッドのIEnumerableを返すために呼び出されます。
  4. 次に、各テストIMethodInfoがITestClassCommand.EnumerateTestCommands(IMethodInfo testMethod)に渡され、ITestCommandsのIEnumerableが取得されます。
  5. 次に、各ITestCommandが実行され、結果を返す機会が与えられます。

上記の例の場合、次のようなものが必要になります。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RunWithMyTestClassCommandAttribute : RunWithAttribute
{
   public RunWithMyTestClassCommandAttribute()
               : base(typeof(MyTestClassCommand)) {}
}

次に、上記の例を次のように装飾できます。

[RunWithMyTestClassCommand]
public class AdditionSpecification
{
  static int result;

  public void Because()
  {
    result = 2 + 2;
  }

  public void Result_is_non_zero()
  {
    Assert.True(result <> 0);
  }

  public void Result_is_correct()
  {
    Assert.Equal(4, result);
  }
}

最後に、MyTestClassCommandでは、EnumerateTestMethods()とEnumerateTestCommands(IMethodInfo testMethod)の間で、特定のロジックを使用して、個々のテストとして実行されるITestCommandインスタンスを構築する機会を得ます。

ところで、この問題を調査する過程で、xUnit.NETフレームワークで小さなバグが発生しました。このバグでは、EnumerateTestMethods()によって生成されたカスタムIMethodInfoが、テストによってアンラップおよび再ラップされていたため、EnumerateTestCommands(..)に表示されませんでした。ランナーまたはその工場の1つ。

この問題をcodeplexのxUnitプロジェクトに提出し、2009年5月30日にxUnit.NET 1.5CTP2で修正されました。

于 2009-06-08T20:13:17.860 に答える
10

xUnit.net の IUseFixture を使用すると、フィクスチャごとのセットアップを行うことができます。したがって、独自のフィクスチャ クラスを定義できます。

public class AdditionFixture : IDisposable
{
  public int Because() 
  {
    return 2 + 2;
  }

  public void Dispose()
  {
   //test tear down code
  }      
}

その後、テスト クラスはこれを実装できます (実装が必要な setFixture を使用)。

public class AdditionSpecification : IUseFixture<AdditionFixture>
{
  int result;

  public void SetFixture(AdditionFixture Fixture)
  {
   result = Fixture.Because();
  }

  [Fact]
  public void Result_is_non_zero()
  {
   Assert.True(result <> 0);
  }

  [Fact]
  public void Result_is_correct()
  {
   Assert.Equal(4, result);
  }
}

xUnit ランナーは、フィクスチャの単一のインスタンスを作成し、各テストを実行する前に SetFixture に渡します。すべてのテストを実行した後、IDisposable を実装している場合、ランナーはフィクスチャを破棄します。それが役立つことを願っています!

codeplex の xUnit wiki には、IUseFixture を実装してフィクスチャをテストするためのデータベース接続を管理する方法の良い例など、より多くの情報があります。

于 2009-06-01T21:27:15.367 に答える