Xunit test Факт несколько раз

У меня есть несколько методов, которые полагаются на случайные вычисления, чтобы сделать предложение, и мне нужно запустить Факт несколько раз, чтобы убедиться, что все в порядке.

Я мог бы включить цикл for в тот факт, который я хочу протестировать, но поскольку есть несколько тестов, в которых я хочу сделать это, я искал более чистый подход, что-то вроде этого атрибута Repeat в junit: http://www.codeaffine.com/2013/04/10/приработки JUnit-тесты-раз-без петель /

Могу ли я легко реализовать что-то подобное в xunit?

Ответ 1

Вам нужно будет создать новый DataAttribute, чтобы сообщить xunit о запуске одного и того же теста несколько раз.

Вот пример, следуя той же идее junit:

public class RepeatAttribute : DataAttribute
{
    private readonly int _count;

    public RepeatAttribute(int count)
    {
        if (count < 1)
        {
            throw new ArgumentOutOfRangeException(nameof(count), 
                  "Repeat count must be greater than 0.");
        }
        _count = count;
    }

    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
        return Enumerable.Repeat(new object[0], _count);
    }
}

С помощью этого кода вам просто нужно изменить Fact на Theory и использовать Repeat следующим образом:

[Theory]
[Repeat(10)]
public void MyTest()
{
    ...
}

Ответ 2

Было то же требование, но принятый код ответов не повторял тесты, поэтому я адаптировал его к:

public sealed class RepeatAttribute : Xunit.Sdk.DataAttribute
{
    private readonly int count;

    public RepeatAttribute(int count)
    {
        if (count < 1)
        {
            throw new System.ArgumentOutOfRangeException(
                paramName: nameof(count),
                message: "Repeat count must be greater than 0."
                );
        }
        this.count = count;
    }

    public override System.Collections.Generic.IEnumerable<object[]> GetData(System.Reflection.MethodInfo testMethod)
    {
        foreach (var iterationNumber in Enumerable.Range(start: 1, count: this.count))
        {
            yield return new object[] { iterationNumber };
        }
    }
}

Хотя в предыдущем примере Enumerable.Repeat использовался, тест выполнялся только 1 раз, так как xUnit не повторяет тест. Вероятно, что-то они изменили некоторое время назад. Переходя к циклу foreach мы можем повторять каждый тест, но мы также предоставляем "номер итерации". При использовании его в тестовой функции вы должны добавить параметр в вашу тестовую функцию и оформить его как Theory как показано здесь:

[Theory(DisplayName = "It should work")]
[Repeat(10)]
public void It_should_work(int iterationNumber)
{
...
}

Это работает для xUnit 2.4.0.

Я создал пакет NuGet , чтобы использовать его на тот случай, если кому-то будет интересно.