Использование атрибута TestCase с двумерным массивом

Я использую NUnit и пытаюсь реализовать тесты для следующего метода: он должен принимать два целых числа и возвращает двумерный массив. Итак, заголовок моего теста выглядит так:

[TestCase(5, 1, new int[,]{{1}, {2}, {3}, {4}, {5}})]
public void MyTestMethod(int a, int b, int[][] r)

Во время компиляции я получил следующую ошибку:

Ошибка CS0182: аргумент атрибута должен быть выражением константы, выражением typeof или выражением создания массива типа параметра атрибута (CS0182)


Я знаю, что это можно сделать с помощью TestCaseSource для ссылки на массивы объектов, таких как ответы на следующие вопросы:

который дает код как:

private object[][] combination_tests =  new [] {
    new object[] {5, 1, new [,]{{1}, {2}, {3}, {4}, {5}}},
};

[Test]
[TestCaseSource("combination_tests")]
public void MyTestMethod(int a, int b, int[,] r)

но у меня все еще есть вопрос: возможно ли это сделать, используя только TestCase атрибут?

2 ответа

Вам абсолютно необходимо иметь одинаковую подпись для вашего метода, т.е.

public void MyTestMethod(int a, int b, int[][] r)
{
    // elided
}

В зависимости от вашей ситуации, у вас есть два варианта, оба из которых используют [TestCase] атрибут, как вы сказали, что вы хотели в вопросе:

Можно ли это сделать, используя только TestCase атрибут?

Я предпочитаю первый вариант, так как он кажется более лаконичным, но оба подойдут под ваши нужды.


Вариант 1: если нет необходимости хранить одну и ту же подпись

Вы можете немного изменить сигнатуру, чтобы вместо массива (не константы времени компиляции) вы передавали строку ( которая является константой времени компиляции), которую можно использовать для получения массива, например:

private static int[][] getArrayForMyTestMethod(string key)
{
    // logic to get from key to int[][]
}

[TestCase(5, 1, "dataset1")]
public void MyTestMethod(int a, int b, string rKey)
{
    int[][] r = getArrayForMyTestMethod(rKey);
    // elided
}

Вариант 2: если необходимо сохранить одинаковую подпись

Если необходимо сохранить одну и ту же сигнатуру для метода, у вас может быть метод-обертка, который делает то же самое, что и вариант 1, т.е.

private static int[][] getArrayForMyTestMethod(string key)
{
    // logic to get from key to int[][]
}

[TestCase(5, 1, "dataset1")]
public void MyTestMethodWrapper(int a, int b, string rKey)
{
    int[][] r = getArrayForMyTestMethod(rKey);
    MyTestMethod(a, b, r);
}

public void MyTestMethod(int a, int b, int[][] r)
{
    // elided
}

Очевидно, вы можете использовать любой тип, который может быть константой времени компиляции вместо string в зависимости от того, как устроены ваши тестовые примеры, но я предложил string потому что таким образом вы сможете дать имя своему тестовому сценарию в NUnit.


В противном случае ваша альтернатива заключается в использовании [TestCaseSource] как вы упомянули в своем вопросе.

Вы можете использовать объект testcasedata для передачи результатов в

    public IEnumerable<TestCaseData> combination_tests()
        {
          yield return new TestCaseData(5,1,new int[,] {{1}, {2}, {3}, {4}, {5}});
        }

    [Test]
    [TestCaseSource("combination_tests")]
    public void test(int a, int b, int[,] r)
        {

            Console.WriteLine(r[0,0] & r[1,0]);

        }

Вы также можете установить категорию теста и имя теста для каждого элемента testCaseData, используя.SetName("xxx") или.SetCategory("xxx"), что может быть удобно для организации тестов.

Другие вопросы по тегам