在 NUnit 中如何添加一个使用另一个测试的所有参数运行的测试?
In NUnit how to add a test that runs with all the parameters of another test?
我有一个参数化测试,可以对特定逻辑进行单元测试。 NUnit TestCaseAttribute
.
捕获了几个测试用例
现在我想使用完全相同的参数来测试稍微不同的逻辑。
我意识到我可以通过不同的属性传递参数 - TestCaseSourceAttribute
并使用相同的源进行多个单元测试。
但我想知道是否可以同时使用 TestCaseAttribute
(我发现在这个特定测试中更方便)并将参数重新用于另一个测试?
我的解决方案涉及反思:
[TestCase(Impl.SqlErrorCode.PartiallyDocumentedColumn, 1978.14, "MyTable", ChangeTypeCode.AddTable, "dbo.MyAuxTable:MyTableId")]
[TestCase(Impl.SqlErrorCode.UndocumentedColumn, 1978.15, "MyAuxTable", ChangeTypeCode.AddTable, "dbo.MyAuxTable:MyAuxTableId")]
[TestCase(Impl.SqlErrorCode.UndocumentedColumn, 1978.16, "MyTable", ChangeTypeCode.AddTable, "dbo.MyTable:MyAuxTableId")]
[TestCase(Impl.SqlErrorCode.NonExistingColumnInComments, 1969.19, "MyTable", ChangeTypeCode.None, "dbo.MyTable:Remarks")]
public async Task AddTableWithBadComments(Impl.SqlErrorCode expectedSqlErrorCode, decimal step, string tableName, int sqlErrorState, string expectedObjectName)
{
// ...
}
private static IEnumerable GetParametersOfAnotherTest(string testName)
{
var testCaseAttrs = typeof(IntegrationTests).GetMethod(testName).GetCustomAttributes<TestCaseAttribute>();
return testCaseAttrs.Select(a => a.Arguments);
}
[TestCaseSource(nameof(GetParametersOfAnotherTest), new object[] { nameof(AddTableWithBadComments) })]
public async Task AddTableWithBadCommentsNoVerify(Impl.SqlErrorCode expectedSqlErrorCode, double _step, string tableName, int sqlErrorState, string expectedObjectName)
{
// A different logic, but with the same parameters.
}
虽然有一些问题。
所以,我的问题是 - 是否有 NUnit 方法 运行 带有测试方法 X 参数的测试方法 Y,其中后者使用 TestCaseAttribute
提供参数?
我用的是nunit 3.7.1
实际答案很短。 NUnit重用参数的方式是TestCaseSourceAttribute
。 :-)
我想我会解释为什么你的解决方案不起作用。
在 NUnit 3+ 中,TestCase
和 TestCaseSource
等属性不仅仅是数据容器。它们实现接口,NUnit 调用这些接口以使属性在特定测试上运行。
您的代码将 TestCaseAttribute
当作参数的数据存储。但该属性实际上做了一些事情,其中一些与 TestCaseSourceAttribute
所做的不同。
从你的代码中,我可以看出你自己想出了一部分。您的第一个方法依赖于将双精度转换为十进制的属性,而您的第二个方法将参数作为双精度。这种差异当然是由于您不能为属性设置小数参数。
不幸的是,对于完整的解决方案,您将不得不复制或考虑两个属性之间的其他差异,这些差异都是由于 C# 对属性参数的限制所致。国际海事组织,这是不值得的。创建 TestCaseData 项目的静态数组并将它们用于两种方法是微不足道的。如果你让你的方法奏效(这是可能的),那么唯一的优势就是它的聪明。 :-)
我有一个参数化测试,可以对特定逻辑进行单元测试。 NUnit TestCaseAttribute
.
现在我想使用完全相同的参数来测试稍微不同的逻辑。
我意识到我可以通过不同的属性传递参数 - TestCaseSourceAttribute
并使用相同的源进行多个单元测试。
但我想知道是否可以同时使用 TestCaseAttribute
(我发现在这个特定测试中更方便)并将参数重新用于另一个测试?
我的解决方案涉及反思:
[TestCase(Impl.SqlErrorCode.PartiallyDocumentedColumn, 1978.14, "MyTable", ChangeTypeCode.AddTable, "dbo.MyAuxTable:MyTableId")]
[TestCase(Impl.SqlErrorCode.UndocumentedColumn, 1978.15, "MyAuxTable", ChangeTypeCode.AddTable, "dbo.MyAuxTable:MyAuxTableId")]
[TestCase(Impl.SqlErrorCode.UndocumentedColumn, 1978.16, "MyTable", ChangeTypeCode.AddTable, "dbo.MyTable:MyAuxTableId")]
[TestCase(Impl.SqlErrorCode.NonExistingColumnInComments, 1969.19, "MyTable", ChangeTypeCode.None, "dbo.MyTable:Remarks")]
public async Task AddTableWithBadComments(Impl.SqlErrorCode expectedSqlErrorCode, decimal step, string tableName, int sqlErrorState, string expectedObjectName)
{
// ...
}
private static IEnumerable GetParametersOfAnotherTest(string testName)
{
var testCaseAttrs = typeof(IntegrationTests).GetMethod(testName).GetCustomAttributes<TestCaseAttribute>();
return testCaseAttrs.Select(a => a.Arguments);
}
[TestCaseSource(nameof(GetParametersOfAnotherTest), new object[] { nameof(AddTableWithBadComments) })]
public async Task AddTableWithBadCommentsNoVerify(Impl.SqlErrorCode expectedSqlErrorCode, double _step, string tableName, int sqlErrorState, string expectedObjectName)
{
// A different logic, but with the same parameters.
}
虽然有一些问题。
所以,我的问题是 - 是否有 NUnit 方法 运行 带有测试方法 X 参数的测试方法 Y,其中后者使用 TestCaseAttribute
提供参数?
我用的是nunit 3.7.1
实际答案很短。 NUnit重用参数的方式是TestCaseSourceAttribute
。 :-)
我想我会解释为什么你的解决方案不起作用。
在 NUnit 3+ 中,TestCase
和 TestCaseSource
等属性不仅仅是数据容器。它们实现接口,NUnit 调用这些接口以使属性在特定测试上运行。
您的代码将 TestCaseAttribute
当作参数的数据存储。但该属性实际上做了一些事情,其中一些与 TestCaseSourceAttribute
所做的不同。
从你的代码中,我可以看出你自己想出了一部分。您的第一个方法依赖于将双精度转换为十进制的属性,而您的第二个方法将参数作为双精度。这种差异当然是由于您不能为属性设置小数参数。
不幸的是,对于完整的解决方案,您将不得不复制或考虑两个属性之间的其他差异,这些差异都是由于 C# 对属性参数的限制所致。国际海事组织,这是不值得的。创建 TestCaseData 项目的静态数组并将它们用于两种方法是微不足道的。如果你让你的方法奏效(这是可能的),那么唯一的优势就是它的聪明。 :-)