按给定顺序执行测试
通常,你的测试应该以执行顺序无关紧要的方式创建。然而,如果你需要打破这个规则,总会有一个边缘情况。
我遇到的一个场景是使用 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);
}
}
}
}
}