English 中文(简体)
Why does Assert.AreEqual(1.0, double.NaN, 1.0) pass?
原标题:

Short question, why does Assert.AreEqual(1.0, double.NaN, 1.0) pass? Whereas Assert.AreEqual(1.0, double.NaN) fails.

Is it a bug in MSTest (Microsoft.VisualStudio.QualityTools.UnitTestFramework) or am I missing something here?

Best regards, Egil.


Update: Should probably add, that the reason behind my question is, that I have a bunch of unit tests that unfortunately passed due to the result of some linear algebraic matrix operation being NaN or (+/-)Infinity. The unit tests are fine, but since Assert.AreEqual on doubles with a delta will pass when actual or/and expected are NaN or Infinity, I was left to believe that the code I was testing was correct.

最佳回答

Be careful. NaN is weird, somewhat like null in many DBMSs, and you shouldn t be comparing values to it (either directly, or with Assert.AreEqual). From the docs for Double.NaN:

Use IsNaN to determine whether a value is not a number. It is not possible to determine whether a value is not a number by comparing it to another value equal to NaN.

double zero = 0;
Console.WriteLine((0 / zero) == Double.NaN);  // prints false
Console.WriteLine(Double.IsNaN(0 / zero));  // prints true

You d have to peer at the internals of Assert(double, double, double) to see what s going on, but in general, you re depending on undefined behavior relative to NaN.

问题回答

The answers are out-of-date. If the bug has been fixed, when, and in which versions of what assembly?

That s correct, it was fixed in VS2013 with the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll assembly, version 10.0.0.0. Present in the legacy GAC, c:windowsassembly, it also has the 10.1.0.0 version.

There is a DLL Hell story here, the 10.1.0.0 version was the one used in VS2010. It had the bug, not properly checking for Double.NaN. Microsoft made a mistake, they fixed 10.1.0.0 but did not change the version number. So anybody that installed VS2010 after installing VS2013 is going to get hurt, it is going to overwrite the DLL with the buggy version.

Unraveling DLL Hell is never that simple, but it appears from the connect article and from the way it works on my machine that they identified the failure mode from the customer s complaint. And provided a fix, delivered in an update. Not clear which, after July 2014. You ll now use v10.0.0.0, the MSTest.exe test runner and the QTAgents have a .config file with a <bindingRedirect> that redirects from 10.1.0.0 to 10.0.0.0 (not a typo). Be sure to obtain the latest update, currently 4. Look in Help + About if you are not sure what update you have installed.

For the record, the fixed code acquired specific checks for Double.NaN, it looks like this:

public static void AreEqual(double expected, double actual, double delta, string message, params object[] parameters)
{
    if ((double.IsNaN(expected) || double.IsNaN(actual)) || double.IsNaN(delta))
    {
        string str = (string) FrameworkMessages.AreEqualDeltaFailMsg((message == null) ? string.Empty : ReplaceNulls(message), expected.ToString(CultureInfo.CurrentCulture.NumberFormat), actual.ToString(CultureInfo.CurrentCulture.NumberFormat), delta.ToString(CultureInfo.CurrentCulture.NumberFormat));
        HandleFail("Assert.AreEqual", str, parameters);
    }
    if (Math.Abs((double) (expected - actual)) > delta)
    {
        string str2 = (string) FrameworkMessages.AreEqualDeltaFailMsg((message == null) ? string.Empty : ReplaceNulls(message), expected.ToString(CultureInfo.CurrentCulture.NumberFormat), actual.ToString(CultureInfo.CurrentCulture.NumberFormat), delta.ToString(CultureInfo.CurrentCulture.NumberFormat));
        HandleFail("Assert.AreEqual", str2, parameters);
    }
}

MSTest uses the following formula for the Assert.AreEqual<double>(expected, actual, delta) method:

if (Math.Abs(expected - actual) > delta)
    Assert.HandleFail("Assert.AreEqual", ...)

The operation reduces to double.NaN > delta, which returns true in this case. Or undefined.





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签