Nunit扩展了ICommandWrapper,如何包装测试柜



我尝试扩展扩展 ICommandWrapper,之后:https://www.skyrise.tech/blog/blog/tech/exting-nunit-3-with-with-command-wrappers/。我发现我也可以扩展TestAttribute,并且它只是有效的,然后我尝试扩展TestCaseAttribute

[AttributeUsage(AttributeTargets.Method), AllowMultiple = true]
public class MyTestCaseAttribute : TestCaseAttribute, IWrapSetUpTearDown
{
    private object[] _args;
    public MyTestCaseAttribute(params object[] args) : base(args)
    {
        _args = args;
    }
    public TestCommand Wrap(TestCommand command)
    {
        return new MyTestCommand(command, _args);
    }
}

MyTestCommand与文章一样扩展了DelegatingTestCommand。问题是,如果我将多个MyTestCaseAttribute s添加到测试方法中,则多次由MyTestCommand.Execute的代码包裹测试方法。

[edit] 示例:
假设MyTestCommand看起来像这样:

public abstract class MyCommandDecorator : DelegatingTestCommand
{
    public override TestResult Execute(TestExecutionContext context)
    private object[] _testCaseArgs;
    protected TestCommandDecorator(TestCommand innerCommand, params object[] args) : base(innerCommand)
    {
        _testCaseArgs = args;
    }
    public override TestResult Execute(TestExecutionContext context)
    {
        DoSomething(_testCaseArgs);
        return context.CurrentResult = innerCommand.Execute(context);
    }
}

假设我用两个 [MyTestCase]属性装饰了一种测试方法:

[MyTestCase(1)]
[MyTestCase(2)]
public void MyTest(int foo)
{
//...
}

所需的行为类似:

DoSomething(1);
MyTest(1);
DoSomething(2);
MyTest(2);

但实际行为是:

DoSomething(2)
DoSomething(1)
MyTest(1)
DoSomething(2)
DoSomething(1)
MyTest(1)

问题的关键是... c#允许您装饰具有属性的方法或类。但是,在Nunit之外不存在单个测试用例 - 没有C#等效 - 因此您无法装饰它。

您的两个属性适用于该方法,并导致Nunit使用该方法生成两个测试用例。但是,您的属性还实现了ICommandWrapper,这会导致Nunit包裹其生成的任何测试用例。Nunit的一部分是寻找测试用例来创建另一部分,就是寻找包装测试用例的属性。这两个部分完全分开。

这就是为什么Nunit在测试案例方法上使用属性来指示诸如忽略案例之类的事情。它不能使用属性,因为属性将适用于该方法生成的每个测试用例。

希望这解释了正在发生的事情。

要解决问题,您的命令包装器应仅应用于该属性的特定实例生成的测试。这意味着您必须参与测试的创建,至少在您的属性记住对其创建的测试的引用的程度上。这有点复杂,但是您应该查看testCaseAttribute的代码,以查看如何创建测试案例。

弄清楚了。

,我可以使用command.Test.ArgumentsTestCaseAttribute S扩展TestAttribute,而是扩展CC_11并获得将包装程序类传递给包装类别的参数。

[AttributeUsage(AttributeTargets.Method), AllowMultiple = true]
public class MyTestAttribute : TestAttribute, IWrapSetUpTearDown
{
    public TestCommand Wrap(TestCommand command)
    {
        return new MyTestCommand(command, command.Test.Arguments);
    }
}
[TestCase(1)]
[TestCase(2)]
[MyTest]
public void MyTest(int foo)
{
//...
}

最新更新