web-dev-qa-db-ja.com

xUnit.netテストでセットアップコードを1回だけ実行する方法

Xunitを使用してテストをセットアップしようとしています。テストの開始時にフォルダー内のすべての画像を削除する必要があります。その後、各メソッドで画像のサイズ変更を行い、その出力のコピーをフォルダーに保存します。フォルダーは一度だけ空にする必要があります。その後、各メソッドが独自の画像をフォルダーに保存します。

IUseFixture<T>を使用すると、すべてのテストの前にClearVisualTestResultFolder関数がまだ呼び出されているため、フォルダー内の画像は1つだけになります。

public class Fixture
{
    public void Setup()
    {
        ImageHelperTest.ClearVisualTestResultFolder();
    }
}

public class ImageHelperTest : IUseFixture<EngDev.Test.Fixture>
{
    public void SetFixture(EngDev.Test.Fixture data)
    {
        data.Setup();
    }

    public static void ClearVisualTestResultFolder()
    {
        // Logic to clear folder
    }
}

コンストラクタにClearVisualTestResultFolderを配置すると、すべてのテストメソッドに対して1回も呼び出されます。すべてのテストメソッドが実行される前に一度だけ実行する必要があります。これを行うにはどうすればよいですか?

必要であれば、ReSharperテストランナーを使用します。

23
Chris

この xUnitディスカッショントピック のガイダンスに従って、Fixtureにコンストラクターを実装し、IDisposableも実装する必要があるようです。以下は、希望どおりに動作する完全なサンプルです。

using System;
using System.Diagnostics;
using Xunit;
using Xunit.Sdk;

namespace xUnitSample
{
    public class SomeFixture : IDisposable
    {
        public SomeFixture()
        {
            Console.WriteLine("SomeFixture ctor: This should only be run once");
        }

        public void SomeMethod()
        {
            Console.WriteLine("SomeFixture::SomeMethod()");
        }

        public void Dispose()
        {
            Console.WriteLine("SomeFixture: Disposing SomeFixture");
        }
    }

    public class TestSample : IUseFixture<SomeFixture>, IDisposable
    {
        public void SetFixture(SomeFixture data)
        {
            Console.WriteLine("TestSample::SetFixture(): Calling SomeMethod");
            data.SomeMethod();
        }

        public TestSample()
        {
            Console.WriteLine("This should be run once before every test " + DateTime.Now.Ticks);
        }

        [Fact]
        public void Test1()
        {
            Console.WriteLine("This is test one.");
        }

        [Fact]
        public void Test2()
        {
            Console.WriteLine("This is test two.");
        }

        public void Dispose()
        {
            Console.WriteLine("Disposing");
        }
    }
}

これをコンソールランナーから実行すると、次の出力が表示されます。

D:\ xUnit> xunit.console.clr4.exe test.dll/html foo.htm xUnit.net console test runner(64-bit .NET 4.0.30319.17929)Copyright(C)2007-11 Microsoft Corporation。

xunit.dll:バージョン1.9.1.1600テストアセンブリ:test.dll

SomeFixture ctor:これは一度だけ実行する必要があります

テスト完了:2/2

SomeFixture:SomeFixtureの破棄

合計2、失敗0、スキップ0、0.686秒

次に、テスト出力ファイルfoo.htmをクラックオープンすると、他のテスト出力が表示されます。

30
nithins

老人 - IUseFixture<T>xUnit.net v1.xのインターフェースは、2つの新しいインターフェースに置き換えられました:IClassFixture<T>およびICollectionFixture<T>。さらに、フィクスチャ値をテストに挿入するメカニズムが、プロパティセッターからコンストラクター引数に変更されました。クラスフィクスチャは一度作成され、同じクラスのすべてのテスト間で共有されます(以前のIUseFixtureと同様)。コレクションフィクスチャは同じ方法で機能しますが、単一のインスタンスが同じテストコレクション内のすべてのテスト間で共有される点が異なります。

17
CodeZila

IUseFixture<T>.SetFixtureは、テストごとに1回呼び出されます。フィクスチャー自体は一度だけ作成されます。

言い換えると、SetFixtureメソッドで何もするべきではなく、Fixtureコンストラクターでトリガーする必要があります。

1回限りのクリーンアップでは、フィクスチャにIDisposable.Disposeを実装します(ただし、必須ではありません)。

テスト間で(場合によっては)状態を共有することは悪い考えであることに注意してください。 TemporaryDirectoryFixtureこれのように を使用するのが最善です。

6
Ruben Bartelink