Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an IComparer for a Nunit CollectionAssert test?

Tags:

c#

nunit

I wish to create the following test in NUnit for the following scenario: we wish to test the a new calculation method being created yields results similar to that of an old system. An acceptable difference (or rather a redefinition of equality) between all values has been defined as

 abs(old_val - new_val) < 0.0001

I know that I can loop through every value from the new list and compare to values from the old list and test the above condition.

How would achieve this using Nunit's CollectionAssert.AreEqual method (or some CollectionAssert method)?

like image 939
Ahmad Avatar asked Aug 24 '11 08:08

Ahmad


2 Answers

The current answers are outdated. Since NUnit 2.5, there is an overload of CollectionAssert.AreEqual that takes a System.Collections.IComparer.

Here is a minimal implementation:

public class Comparer : System.Collections.IComparer
{
  private readonly double _epsilon;

  public Comparer(double epsilon)
  {
    _epsilon = epsilon;
  }

  public int Compare(object x, object y)
  {
    var a = (double)x;
    var b = (double)y;

    double delta = System.Math.Abs(a - b);
    if (delta < _epsilon)
    {
      return 0;
    }
    return a.CompareTo(b);
  }
}


[NUnit.Framework.Test]
public void MyTest()
{
  var a = ...
  var b = ...
  NUnit.Framework.CollectionAssert.AreEqual(a, b, new Comparer(0.0001));
}
like image 107
Sebastian Negraszus Avatar answered Oct 24 '22 05:10

Sebastian Negraszus


Well there is method from the NUnit Framework that allows me to do tolerance checks on collections. Refer to the Equal Constraint. One uses the AsCollection and Within extension methods. On that note though I am not 100% sure regarding the implications of this statement made

If you want to treat the arrays being compared as simple collections, use the AsCollection modifier, which causes the comparison to be made element by element, without regard for the rank or dimensions of the array.

 [Test]
 //[ExpectedException()]
 public void CheckLists_FailsAt0()
 {
    var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
    var result1 = new[] { -0.0004, 0.43520, 1.3454, 345345.0980 };
    Assert.That(result1, Is.EqualTo(expected).AsCollection.Within(0.0001), "fail at [0]"); // fail on [0]    
    }

[Test]
//[ExpectedException()]
public void CheckLists_FailAt1()
{
    var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
    var result1a = new[] {  0.0001000000 , 0.4348245000 , 1.3450234000 , 345345.0975980000  };                      
    Assert.That(result1a, Is.EqualTo(expected).AsCollection.Within(0.0001), "fail at [1]"); // fail on [3]        
    }

[Test]    
public void CheckLists_AllPass_ForNegativeDiff_of_1over10001()
{
    var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
    var result2 = new[] {  0.00009900 , 0.43532350 , 1.34552240 , 345345.09809700 };
    Assert.That(result2, Is.EqualTo(expected).AsCollection.Within(0.0001)); // pass      
 }

 [Test]
 public void CheckLists_StillPass_ForPositiveDiff_of_1over10001()
 {
    var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
    var result3 = new[] {  0.00010100 ,  0.43532550  , 1.34552440 , 345345.09809900 };
    Assert.That(result3, Is.EqualTo(expected).AsCollection.Within(0.0001)); // pass
 }
like image 28
Ahmad Avatar answered Oct 24 '22 06:10

Ahmad