如何在ParameterizedMethodSuite中编写外接程序以扩展NUnit testcases中的单个测试

如何在ParameterizedMethodSuite中编写外接程序以扩展NUnit testcases中的单个测试,nunit,add-in,Nunit,Add In,我正在编写一个扩展nunitestmethod并重写其RecordException()方法的加载项,以提供有关测试的更多信息,这些信息基于几个自定义属性,测试可以使用这些属性进行标记 到目前为止,我已经通过使用ITestDecorator扩展成功地创建了一个扩展单个测试的加载项,该加载项由[Test]属性标记。当我尝试对测试用例执行相同的操作时,问题就出现了,使用parametrised[TestCase()]属性进行标记。在本例中,NUnit创建了一个所谓的参数化方法套件,而我似乎找不到一种

我正在编写一个扩展
nunitestmethod
并重写其
RecordException()
方法的加载项,以提供有关测试的更多信息,这些信息基于几个自定义属性,测试可以使用这些属性进行标记

到目前为止,我已经通过使用
ITestDecorator
扩展成功地创建了一个扩展单个测试的加载项,该加载项由
[Test]
属性标记。当我尝试对测试用例执行相同的操作时,问题就出现了,使用parametrised
[TestCase()]
属性进行标记。在本例中,NUnit创建了一个所谓的
参数化方法套件
,而我似乎找不到一种方法来将我的类(从NUnitestMethod继承)注入到这样的套件中

不久前,我发布了一个关于NUnit邮件列表的问题,没有得到任何答案。也许这里有一些修女大师,他们遇到了同样的问题,能帮我解决吗

有关我的项目的代码示例,请参阅NUnit邮件列表上的帖子:

编辑:
在深入研究NUnit源代码之后,我终于找到了一种实现我想要的东西的方法,尽管方法不同。
就我所见,无法使用您自己的测试方法来填充
ParameterizedMethodSuite
,这些方法继承自
NunitestMethod
,因为我无法访问派生类中的私有参数构造,因此无法设置它们。
我最终扩展了
ParameterizedMethodSuite
并重写了
Run()
方法,随后修改了从
base.Run()返回的
TestResult
为了保持一致性,扩展
nunitestmethod
的类现在还重写
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;
    }
}
[NUnitAddin(Name=“Custom Tag Attribute Decorator”,Description=“为使用自定义属性标记的测试输出附加信息。”)]
公共类标记装饰器:ITestDecorator,IAddin
{
公共测试(测试测试,MemberInfo成员)
{
List tags=Reflect.GetAttributes(member,false).OfType().Cast().ToList();
如果(tags.Count==0)
{
回归试验;
}
如果(测试为非测试方法)
{
返回新的TestMethodExtension((作为nunitestMethod.Method进行测试),标记);
}
if(测试参数化方法套件)
{
ParameterizedMethodSuite=测试为ParameterizedMethodSuite;
ParameterizedMethodSuiteExtension outputSuite=新的ParameterizedMethodSuiteExtension(成员为MethodInfo,标记);
NUnitFramework.ApplyCommonatAttributes(成员,outputSuite);
outputSuite.RunState=suite.RunState;
outputSuite.IgnoreReason=suite.IgnoreReason;
foreach(suite.Tests中的nunitestmethodtestmethod)
{
Add(testMethod);
}
返回输出套件;
}
回归试验;
}
公共bool安装(IExtensionHost主机)
{
IExtensionPoint testDecorators=host.GetExtensionPoint(“testDecorators”);
if(testDecorators==null)
返回false;
testDecorators.Install(这个);
返回true;
}
}
公共静态类TagExtensionHandler
{
公共静态void ModifyTestResult(TestResult TestResult,列表标记)
{
StringBuilder消息=新建StringBuilder();
message.AppendLine(“相关:”);
foreach(tags.OfType()中的ITestTag taggedAttrib.Select(attrib=>attrib))
{
消息。追加(“”);
message.AppendLine(taggedAttrib.GetInfo());
message.AppendLine();
}
message.AppendLine();
Append(testResult.message);
testResult.SetResult(testResult.ResultState,message.ToString(),testResult.StackTrace,testResult.FailureSite);
}
}
公共类ParameterizedMethodSuite扩展:ParameterizedMethodSuite
{
私有只读列表_标记;
公共参数化MethodSuiteExtension(MethodInfo方法,列表标记)
:基准(方法)
{
_标签=标签;
}
公共覆盖测试结果运行(EventListener侦听器、ITestFilter筛选器)
{
TestResult=base.Run(监听器、过滤器);
foreach(result.Results中的TestResult子结果)
{
TagExtensionHandler.ModifyTestResult(子结果,_标记);
}
返回结果;
}
}
公共类TestMethodExtension:NunitestMethod
{
私有只读列表_标记;
公共TestMethodExtension(MethodInfo MethodInfo,列表标记)
:base(methodInfo)
{
_标签=标签;
}
公共覆盖测试结果运行(EventListener侦听器、ITestFilter筛选器)
{
TestResult=base.Run(监听器、过滤器);
TagExtensionHandler.ModifyTestResult(结果,_标记);
返回结果;
}
}