按給定順序執行測試

通常,你的測試應該以執行順序無關緊要的方式建立。然而,如果你需要打破這個規則,總會有一個邊緣情況。

我遇到的一個場景是使用 R.NET,在給定的過程中,你只能初始化一個 R 引擎,一旦處理完就無法重新初始化。我的一個測試恰好處理了處理引擎的問題,如果這個測試在任何其他測試之前執行,它們就會失敗。

你將在下面找到我使用 Nunit 按順序執行的程式碼片段。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using RSamples;
 
public class OrderedTestAttribute : Attribute
{
    public int Order { get; set; }

    public OrderedTestAttribute(int order)
    {
        this.Order = order;
    }
}

public class TestStructure
{
    public Action Test;
}

public class SampleTests
{
    [TearDown]
    public void CleanUpAfterTest()
    {
        REngineExecutionContext.ClearLog();
    }

    [OrderedTest(0)]
    public void Test1(){}

    [OrderedTest(1)]
    public void Test2(){}

    [OrderedTest(2)]
    public void Test3(){}

    [TestCaseSource(sourceName: "TestSource")]
    public void MainTest(TestStructure test)
    {
        test.Test();
    }

    public static IEnumerable<TestCaseData> TestSource
    {
        get
        {
            var assembly = Assembly.GetExecutingAssembly();
            Dictionary<int, List<MethodInfo>> methods = assembly
                .GetTypes()
                .SelectMany(x => x.GetMethods())
                .Where(y => y.GetCustomAttributes().OfType<OrderedTestAttribute>().Any())
                .GroupBy(z => z.GetCustomAttribute<OrderedTestAttribute>().Order)
                .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

            foreach (var order in methods.Keys.OrderBy(x => x))
            {
                foreach (var methodInfo in methods[order])
                {
                    MethodInfo info = methodInfo;
                    yield return new TestCaseData(
                        new TestStructure
                        {
                            Test = () =>
                            {
                                object classInstance = Activator.CreateInstance(info.DeclaringType, null);
                                info.Invoke(classInstance, null);
                            }
                        }).SetName(methodInfo.Name);
                }
            }
        }
    }
}