Search code examples
c#visual-studiounit-testing.net-6.0

Unit test runs only once with array as parameter


I have two unit tests as follows:

    [DataTestMethod]
    [DataRow(1, 1, 2)]
    [DataRow(2, 2, 4)]
    [DataRow(3, 3, 6)]
    public void AddTest1(int x, int y, int expected)
    {
        Assert.AreEqual(expected, x + y);
    }


    [DataTestMethod]
    [DataRow(new int[] { 1, 2, 3, 4 }, new int[] { 1, 3, 6, 10 })]
    [DataRow(new int[] { 1, 1, 1, 1, 1 }, new int[] { 1, 2, 3, 4, 5 })]
    [DataRow(new int[] { 3, 1, 2, 10, 1 }, new int[] { 3, 4, 6, 16, 17 })]
    public void AddTest2(int[] input, int[] expectedOutput)
    {
        Assert.AreEqual(input[0], expectedOutput[0]);
    }

The first unit test runs 3 times, once for each data row. The second unit test only runs once for the first DataRow.

How can I run the second UnitTests with the arrays once for each DataRow as well?


Solution

  • Most test frameworks require the test cases to use compile-time constants as parameters.

    This works because the parameters are constant at compile time:

    [DataTestMethod]
    [DataRow(1, 1, 2)]
    [DataRow(2, 2, 4)]
    [DataRow(3, 3, 6)]
    public void AddTest1(int x, int y, int expected)
    {
        Assert.AreEqual(expected, x + y);
    }
    

    This doesn't work because you're not using compile-time constants:

    [DataTestMethod]
    [DataRow(new int[] { 1, 2, 3, 4 }, new int[] { 1, 3, 6, 10 })]
    [DataRow(new int[] { 1, 1, 1, 1, 1 }, new int[] { 1, 2, 3, 4, 5 })]
    [DataRow(new int[] { 3, 1, 2, 10, 1 }, new int[] { 3, 4, 6, 16, 17 })]
    public void AddTest2(int[] input, int[] expectedOutput)
    {
        Assert.AreEqual(input[0], expectedOutput[0]);
    }
    

    The new keyword with an array doesn't allow the test framework to differentiate (looking at the image you linked, it just says System.Int32[]).

    A workaround might be this:

    [DataTestMethod]
    [DataRow(0, new int[] { 1, 2, 3, 4 }, new int[] { 1, 3, 6, 10 })]
    [DataRow(1, new int[] { 1, 1, 1, 1, 1 }, new int[] { 1, 2, 3, 4, 5 })]
    [DataRow(2, new int[] { 3, 1, 2, 10, 1 }, new int[] { 3, 4, 6, 16, 17 })]
    public void AddTest2(int run, int[] input, int[] expectedOutput)
    {
        Assert.AreEqual(input[0], expectedOutput[0]);
    }
    

    That way, the different test cases can be differentiated by a compile-time constant.