我打算将所有测试用例存储在一个 excel 文件中,其中的列指示测试方法名称、参数和预期结果;但是,我发现 TestCaseSource 只是将所有测试用例分配给每个测试方法。我想知道有什么方法可以让 NUnit 根据我放在电子表格中的方法名称为方法选择测试用例?
谢谢。
我打算将所有测试用例存储在一个 excel 文件中,其中的列指示测试方法名称、参数和预期结果;但是,我发现 TestCaseSource 只是将所有测试用例分配给每个测试方法。我想知道有什么方法可以让 NUnit 根据我放在电子表格中的方法名称为方法选择测试用例?
谢谢。
有一种方法可以做到这一点。例如,正如您提到的,您可以创建自定义属性。
这个想法是将测试的名称传递给TestCaseSource
.
您可以通过创建TestCaseSource
为单独的类来做到这一点。
一、TestCaseSource
类:
public class SpreadSheetTestCaseSource
{
[ThreadStatic]
public static string TestName = String.Empty;
public static IEnumerable TestCases
{
get
{
SpreadSheetTestCaseProvider.GetTestCases()
.Where(testCase => testCase.TestName == TestName);
}
}
}
然后属性:
public class MyTestCaseSourceAttribute : TestCaseSourceAttribute
{
public MyTestCaseSourceAttribute(Type sourceType, string sourceName,
[CallerMemberName] string name = null)
: base(sourceType, sourceName)
{
SpreadSheetTestCaseSource.TestName = name;
}
//Another two members impl.
}
并测试:
[TestFixture]
public class TestClass
{
[MyTestCaseSource(typeof(SpreadSheetTestCaseSource), "TestCases")]
public void TestMethod()
{
//Test logic
}
}
SpeadSheetTestCaseSource.TestName
是线程静态的。所以你可以并行运行测试。
这不是 NUnit 直接支持的功能。各种 TestCaseSource 类型属性无法根据输入提供测试方法。
一个选项是为每个测试方法创建一个 TestCaseSource。其中每一个都是一个简单的包装器,将方法名称传递给单个内部方法。该内部方法将读取 Excel 文件,并且只返回给定方法名称的行。
伪代码;
[TestCaseSource(nameof(TestMethodOneSource))]
public void TestMethodOne(int x, int y, int expected)
{
Assert.That(x + y, Is.EqualTo(expected));
}
public static IEnumerable<object[]> TestMethodOneSource() =>
ReadExcel(nameof(TestMethodOne));
private static IEnumerable<object[]> ReadExcel(string method)
{
// Open and start reading Excel
for(var row in rows)
{
if(row[0] == method)
{
// Return objects minus the method
yield return new [] {row[1], ..., row[n]};
}
}
}