Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the 'TestCase' attribute with a two-dimensional array

I'm using NUnit and trying to implement tests for the following method: It should accept two integers and returns two dimensional array. So, header of my test looks like:

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

During compilation I've got the following error:

Error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type (CS0182)


I know it can be done using TestCaseSource to refer to object arrays like the answers to the following questions:

  • How do I put new List {1} in an NUNIT TestCase?
  • NUnit Sequential Attribute with arrays in Values

which gives code like:

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)

but I still have the question: is it possible to do that with using only the TestCase attribute?

like image 608
mnlaptev Avatar asked Apr 18 '15 18:04

mnlaptev


People also ask

How do you use a two dimensional array?

Accessing Elements of Two-Dimensional Arrays Elements in two-dimensional arrays are commonly referred by x[i][j] where 'i' is the row number and 'j' is the column number. For example: int[][] arr = new int[10][20]; arr[0][0] = 1; The above example represents the element present in first row and first column.

How do you display an element in a two dimensional array?

Accessing Elements of Two-Dimensional Arrays: Elements in Two-Dimensional arrays are accessed using the row indexes and column indexes. Example: int x[2][1]; The above example represents the element present in the third row and second column.

How two dimensional array is used explain with example?

Here i and j are the size of the two dimensions, i.e i denotes the number of rows while j denotes the number of columns. Example: int A[10][20]; Here we declare a two-dimensional array in C, named A which has 10 rows and 20 columns.

What is a 2-dimensional array in Python?

A 2D array in python is a two-dimensional data structure stored linearly in the memory. It means that it has two dimensions, the rows and the columns, and thus it also represents a matrix.


2 Answers

Is it absolutely necessary for you to have the same signature for your method, i.e.

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

Depending on your situation, you have two options available, both of which use the [TestCase] attribute as you said you wanted in the question:

is it possible to do that with using only the TestCase attribute?

I prefer the first option as it feels more concise, but both will suit your needs.


Option 1: If it is NOT necessary to keep the same signature

You could modify the signature slightly so that instead of an array (not compile-time constant), you pass in a string (which is compile-time constant) which can be used to obtain the array instead, e.g.

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
}

Option 2: If it IS necessary to keep the same signature

If it is necessary to keep the same signature for the method, you could have a wrapper method that does the same as option 1, i.e.

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
}

Obviously you could use any type which can be compile-time constant instead of a string depending on the way your test cases are constructed, but I suggested a string because you'd be able to give a name to your test case in the NUnit runner that way.


Otherwise your alternative is to use [TestCaseSource] as you mentioned in your question.

like image 113
Wai Ha Lee Avatar answered Sep 20 '22 14:09

Wai Ha Lee


You can use the testcasedata object to pass the results in

    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]);

        }

You can also set the test category and test name for each testCaseData item using .SetName("xxx") or .SetCategory("xxx") which can be nice for organizing the tests.

like image 22
Brendan Connolly Avatar answered Sep 20 '22 14:09

Brendan Connolly