NUnit extension ICommandWrapper Как обернуть TestCase? - PullRequest
1 голос
/ 23 мая 2019

Я попытался расширить расширение ICommandWrapper, следуя этой статье: https://www.skyrise.tech/blog/tech/extending-nunit-3-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)

Ответы [ 2 ]

2 голосов
/ 23 мая 2019

Ключ к вашей проблеме заключается в следующем ... C # позволяет вам украшать метод или класс атрибутом.Но отдельный тестовый пример не существует вне NUnit - нет эквивалента в C # - поэтому вы не можете его украсить.

IOW ваши два атрибута применяются к методу и заставляют NUnit использовать этот метод для генерациидва теста.Тем не менее, ваши атрибуты также реализуют ICommandWrapper, что заставляет NUnit оборачивать любые тестовые случаи, которые он генерирует.Одна часть NUnit ищет тестовые случаи, для создания другой части ищет атрибуты для переноса тестовых случаев.Эти две части полностью разделены.

Вот почему NUnit использует свойства метода тестового примера для указания таких вещей, как игнорирование регистра.Он не может использовать атрибут, потому что атрибут будет применяться к каждому тестовому примеру , созданному этим методом.

Надеюсь, это объясняет, что происходит.

Чтобы пройти мимопроблема, ваша командная оболочка должна применяться только к тесту, который был сгенерирован этим конкретным экземпляром атрибута.Это означает, что вы должны участвовать в создании теста, по крайней мере, в той степени, в которой ваш атрибут запоминает ссылку на созданный тест.Это немного сложно, но вы должны посмотреть на код для TestCaseAttribute, чтобы увидеть, как создается контрольный пример.

0 голосов
/ 24 мая 2019

Понял.

Вместо расширения TestCaseAttribute я могу расширить TestAttribute и получить аргументы для передачи в класс-оболочку из стандартных TestCaseAttribute s, используя command.Test.Arguments.

[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)
{
//...
}
...