web-dev-qa-db-ja.com

xUnitでテストケースシーケンスを設定する方法

XUnitテストケースをC#で記述しました。そのテストクラスには非常に多くのメソッドが含まれています。テストケース全体を順番に実行する必要があります。 xUnitでテストケースシーケンスを設定するにはどうすればよいですか?

27
Pankaj Saha

XUnit 2. *では、これはTestCaseOrderer属性を使用して順序付け戦略を指定することで実現できます。これは、各テストで注釈が付けられた属性を参照して順序を示すために使用できます。

例えば:

注文戦略

[Assembly: CollectionBehavior(DisableTestParallelization = true)] 

public class PriorityOrderer : ITestCaseOrderer
{
    public IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
    {
        var sortedMethods = new SortedDictionary<int, List<TTestCase>>();

        foreach (TTestCase testCase in testCases)
        {
            int priority = 0;

            foreach (IAttributeInfo attr in testCase.TestMethod.Method.GetCustomAttributes((typeof(TestPriorityAttribute).AssemblyQualifiedName)))
                priority = attr.GetNamedArgument<int>("Priority");

            GetOrCreate(sortedMethods, priority).Add(testCase);
        }

        foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
        {
            list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name));
            foreach (TTestCase testCase in list)
                yield return testCase;
        }
    }

    static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
    {
        TValue result;

        if (dictionary.TryGetValue(key, out result)) return result;

        result = new TValue();
        dictionary[key] = result;

        return result;
    }
}

属性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestPriorityAttribute : Attribute
{
    public TestPriorityAttribute(int priority)
    {
        Priority = priority;
    }

    public int Priority { get; private set; }
}

テストケース

[TestCaseOrderer("FullNameOfOrderStrategyHere", "OrderStrategyAssemblyName")]
public class PriorityOrderExamples
{
    [Fact, TestPriority(5)]
    public void Test3()
    {
        // called third
    }

    [Fact, TestPriority(0)]
    public void Test2()
    {
      // called second
    }

    [Fact, TestPriority(-5)]
    public void Test1()
    {
       // called first
    }

}

xUnit 2. *サンプルの注文 ここ

31
KnowHoper

Testpriority: this ページの下部。

[PrioritizedFixture]
public class MyTests
{
    [Fact, TestPriority(1)]
    public void FirstTest()
    {
        // Test code here is always run first
    }
    [Fact, TestPriority(2)]
    public void SeccondTest()
    {
        // Test code here is run second
    }
}

ところで、私は今、同じ問題を抱えています。はい、それはクリーンなアートではありません。しかし、QAは手動テストを望んでいたので、特定の順序での自動テストはすでに彼らにとって大きな飛躍でした。

19
Andreas Reiff

仕様ではできません。それは、誰かが欲望によって、または偶然にそれらのいずれかを取得するのを防ぐために、意図的にランダムになっています。

ランダム性は特定のTestクラスにのみ適用されるため、ネストされたクラス内の順序を制御するアイテムをラップすることで目標を達成できる可能性がありますが、その場合でも、いつでもランダムな順序になります。クラスに3つ以上のテストメソッドがある。

フィクスチャまたはコンテキストの構築を管理しようとしている場合、組み込みのIUseFixture<T>メカニズムが適切な場合があります。例については xUnitチートシート を参照してください。

しかし、あなたは本当にあなたが何をしようとしているのかについてもっと私たちに言う必要があります、さもなければ私達は推測をしなければなりません。

1
Ruben Bartelink

テストに優先順位を付ける必要がある場合(おそらくユニットテストではない)、 Xunit.Priority を使用できます。私はいくつかの統合テストにそれを使用しており、単純なケースのシナリオでは、優先順位付けクラスを記述する必要がないため、オーバーヘッドがなく、非常に簡単に機能します。

1
MarcolinoPT