Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I compare doubles using a specified tolerance in NUnit?

Tags:

c#

nunit

I am currently developing a C# P/invoke wrapper to a DLL that is part of my product. I have no experience with C# and this is the first significant C# coding I have done. I am acutely aware that I am lacking a lot of knowledge of the finer points and idioms of the language.

My question concerns the unit tests that I am writing for which I am using NUnit. I have a need to compare the values of double[] variables. If I use Assert.AreEqual(...) to do this then the values are compared for exact equality. However, I would like to compare up to a tolerance. There are AreEqual() overloads for scalar real values that admit a delta parameter. However, I have not been able to find an equivalent for arrays. Have I missed something obvious?

At the moment I have solved the problem with the following code:

class Assert : NUnit.Framework.Assert
{
    public static void AreEqual(double[] expected, double[] actual, double delta)
    {
        AreEqual(expected.Length, actual.Length);
        for (int i = 0; i < expected.Length; i++)
        {
            AreEqual(expected[i], actual[i], delta);
        }
    }
}

Whilst this appears to work I wonder if there is a cleaner solution available. In particular I am concerned that using the same name for my derived class is, not only poor style, but could lead to un-anticipated problems down the road.

I would have like to use extension methods but I understand they are only viable for when there is an instance of the class under extension. Of course, I only ever call static methods on the Assert class.

I'm sorry if this seems a bit nebulous, but my instincts tell me that I'm not doing this the best way and I would like to know how to do it right.

like image 414
David Heffernan Avatar asked Nov 17 '11 09:11

David Heffernan


People also ask

How do I compare two objects in NUnit?

Just install ExpectedObjects from Nuget, you can easily compare two objects's property value, each object value of collection, two composed object's value and partial compare property value by anonymous type. Reference: ExpectedObjects github. Introduction of ExpectedObjects.


1 Answers

Since the introduction of the fluent assertion syntax in NUnit, the Within() method has been available for this purpose:

double actualValue = 1.989;
double expectedValue = 1.9890;
Assert.That(actualValue, Is.EqualTo(expectedValue).Within(0.00001));
Assert.That(actualValue, Is.EqualTo(expectedValue).Within(1).Ulps);
Assert.That(actualValue, Is.EqualTo(expectedValue).Within(0.1).Percent);

For collections, the default behaviour of Is.EqualTo() is to compare the collections' members individually, with these individual comparisons being modified by Within(). Hence, you can compare two arrays of doubles like so:

var actualDoubles = new double[] {1.0 / 3.0, 0.7, 9.981};
var expectedDoubles = new double[] { 1.1 / 3.3, 0.7, 9.9810};
Assert.That(actualDoubles, Is.EqualTo(expectedDoubles).Within(0.00001));
Assert.That(actualDoubles, Is.EqualTo(expectedDoubles).Within(1).Ulps);
Assert.That(actualDoubles, Is.EqualTo(expectedDoubles).Within(0.1).Percent);

This will compare each element of actualDoubles to the corresponding element in expectedDoubles using the specified tolerance, and will fail if any are not sufficiently close.

like image 118
Peter Avatar answered Oct 28 '22 07:10

Peter