0

I want to test the simple + operator with several types of numbers: int, float, double ...

To do this, I want to use Nunit TestCaseSource attribute. So far, the only way I found to do it is the following:

public class TestAdditionExample
{
    
    public static IEnumerable<TestCaseData> GetTestsCasesInts()
    {
        yield return new TestCaseData(1, 2, 3);
        yield return new TestCaseData(1, -2, -1);
    }
    
    public static IEnumerable<TestCaseData> GetTestsCasesFloats()
    {
        yield return new TestCaseData(1.03f, 2.1f, 3.13f);
        yield return new TestCaseData(1.03f, -2.1f, -1.07f);
    }

    public static IEnumerable<TestCaseData> GetTestsCasesDoubles()
    {
        yield return new TestCaseData(1.03, 2.1, 3.13);
        yield return new TestCaseData(1.03, -2.1, -1.07);
    }
    
    [Test, TestCaseSource(nameof(GetTestsCasesInts))]
    public void TestAdditionOfInts(int a, int b, int c)
    {
        Assert.AreEqual(a+b, c);
    }
    
    [Test, TestCaseSource(nameof(GetTestsCasesFloats))]
    public void TestAdditionOfFloats(float a, float b, float c)
    {
        Assert.AreEqual(a+b, c);
    }
    
    [Test, TestCaseSource(nameof(GetTestsCasesDoubles))]
    public void TestAdditionOfDoubles(double a, double b, double c)
    {
        Assert.AreEqual(a+b, c);
    }
}

As you can see, because the type of the argument must be specified as a test function parameter, I have to create three identical tests functions (except the argument type), and three set of TestCaseSource.

Would you think of a better, more elegant solution, to do this ?

NPras
  • 3,135
  • 15
  • 29
Milan
  • 1,547
  • 1
  • 24
  • 47

2 Answers2

1

You could make this work with dynamics:

public class TestAdditionExample
{
    
    public static IEnumerable<dynamic> GetTestsCases()
    {
        yield return new TestCaseData(1, 2, 3);
        yield return new TestCaseData(1, -2, -1);
        yield return new TestCaseData(1.03f, 2.1f, 3.13f);
        yield return new TestCaseData(1.03f, -2.1f, -1.07f);
        yield return new TestCaseData(1.03, 2.1, 3.13);
        yield return new TestCaseData(1.03, -2.1, -1.07);
    }
    
    [Test, TestCaseSource(nameof(GetTestsCases))]
    public void TestAddition(dynamic a, dynamic b, dynamic c) 
    {
        Assert.AreEqual(a+b, c);
    }
}
Sean Manton
  • 136
  • 7
  • thanks! I will try that tomorrow, pretty sure it will work – Milan Feb 24 '22 at 03:44
  • Unfortunately the solution did not work, this is because I am testing under Unity, the function under test is a generic one and I am missing the Microsoft.CSharp.dll to resolve the generic type from the dynamic type But at least, I learned something new, so thanks – Milan Feb 24 '22 at 15:57
0

Here is the solution I found without using dynamics. Fun fact, this solution cannot be applied to the example I gave at the beginning of this thread, because + cannot be used with Generics

public static IEnumerable<TestCaseData> UintsPortsCases()
{
    foreach (var (key, value) in UintsProperties)
    {
        yield return new TestCaseData(key, value, value + 2).Returns(null);
        yield return new TestCaseData(key, value, value - 2).Returns(null);
    }
}

public static IEnumerable<TestCaseData> FloatsPortsCases()
{
    foreach (var (key, value) in FloatsProperties)
    {
        yield return new TestCaseData(key, value, value + 0.001f).Returns(null);
        yield return new TestCaseData(key, value, value - 0.001f).Returns(null);
    }
}


[UnityTest, TestCaseSource(nameof(UintsPortsCases)), TestCaseSource(nameof(FloatsPortsCases))]
public IEnumerator When_PortValueIsChanged_PointOutput_IsChanged<T>(string portName, T referenceValue, T modifiedValue)
{
    yield return RuntimeTools.WaitForFrameCount(5);
    CheckPropertyChangedCallback(portName, referenceValue, modifiedValue);
}

private void CheckPropertyChangedCallback<T>(string propertyName, T referenceValue, T modifiedValue) {};

Still need two functions to declare the test cases (or one function per type of number), but the test itself can be executed in a single function.

Milan
  • 1,547
  • 1
  • 24
  • 47