我正在编写一个插件,该插件将扩展NUnitTestMethod
和覆盖其RecordException()
方法,以提供有关测试的更多信息,基于可以标记测试的几个自定义属性。
到目前为止,我已经成功地创建了一个插件来扩展单个测试,[Test]
通过使用扩展来标记属性ITestDecorator
。当我尝试对以参数化[TestCase()]
属性标记的测试用例做很多相同的事情时,就会出现问题。在这种情况下,NUnit 创建了一个所谓的ParametrizedMethodSuite
.
前段时间我发布了一个关于 NUnit 邮件列表的问题,但没有得到任何答案。也许这里有一些NUnit大师,遇到同样的问题可以帮助我吗?
有关我项目中的代码示例,请参阅 NUnit 邮件列表中的帖子:
https ://groups.google.com/d/topic/nunit-discuss/dZW0Nc8N2LM/discussion
编辑:
在深入研究了 NUnit 源代码之后,我终于找到了一种实现我想要的方法,尽管是以不同的方式。
据我所知,不可能ParameterizedMethodSuite
使用您自己的测试方法进行填充,NUnitTestMethod
因为我无法访问派生类中的私有参数构造,因此无法设置它们。
我最终扩展ParameterizedMethodSuite
和覆盖了Run()
方法,随后修改了TestResult
从返回的base.Run()
一致性,NUnitTestMethod
现在扩展的类也覆盖了Run()
方法。
在这个过程中,我还发现了一个有趣的异常:TestResult.StackTrace
有一个setter,而TestResult.Message
没有。由于我实际上需要修改消息,因此我被迫通过该SetResult()
方法并更新所有内容。
[NUnitAddin(Name = "Custom Tag Attribute Decorator", Description = "Outputs additional information for tests tagged with custom attributes.")]
public class TagDecorator : ITestDecorator, IAddin
{
public Test Decorate(Test test, MemberInfo member)
{
List<Attribute> tags = Reflect.GetAttributes(member, false).OfType<ITestTag>().Cast<Attribute>().ToList();
if (tags.Count == 0)
{
return test;
}
if (test is NUnitTestMethod)
{
return new TestMethodExtension((test as NUnitTestMethod).Method, tags);
}
if (test is ParameterizedMethodSuite)
{
ParameterizedMethodSuite suite = test as ParameterizedMethodSuite;
ParameterizedMethodSuiteExtension outputSuite = new ParameterizedMethodSuiteExtension(member as MethodInfo, tags);
NUnitFramework.ApplyCommonAttributes(member, outputSuite);
outputSuite.RunState = suite.RunState;
outputSuite.IgnoreReason = suite.IgnoreReason;
foreach (NUnitTestMethod testMethod in suite.Tests)
{
outputSuite.Add(testMethod);
}
return outputSuite;
}
return test;
}
public bool Install(IExtensionHost host)
{
IExtensionPoint testDecorators = host.GetExtensionPoint("TestDecorators");
if (testDecorators == null)
return false;
testDecorators.Install(this);
return true;
}
}
public static class TagExtensionHandler
{
public static void ModifyTestResult(TestResult testResult, List<Attribute> tags)
{
StringBuilder message = new StringBuilder();
message.AppendLine("Related to:");
foreach (ITestTag taggedAttrib in tags.OfType<ITestTag>().Select(attrib => attrib))
{
message.Append(" ");
message.AppendLine(taggedAttrib.GetInfo());
message.AppendLine();
}
message.AppendLine();
message.Append(testResult.Message);
testResult.SetResult(testResult.ResultState, message.ToString(), testResult.StackTrace, testResult.FailureSite);
}
}
public class ParameterizedMethodSuiteExtension : ParameterizedMethodSuite
{
private readonly List<Attribute> _tags;
public ParameterizedMethodSuiteExtension(MethodInfo method, List<Attribute> tags)
: base(method)
{
_tags = tags;
}
public override TestResult Run(EventListener listener, ITestFilter filter)
{
TestResult result = base.Run(listener, filter);
foreach (TestResult subResult in result.Results)
{
TagExtensionHandler.ModifyTestResult(subResult, _tags);
}
return result;
}
}
public class TestMethodExtension : NUnitTestMethod
{
private readonly List<Attribute> _tags;
public TestMethodExtension(MethodInfo methodInfo, List<Attribute> tags)
: base(methodInfo)
{
_tags = tags;
}
public override TestResult Run(EventListener listener, ITestFilter filter)
{
TestResult result = base.Run(listener, filter);
TagExtensionHandler.ModifyTestResult(result, _tags);
return result;
}
}