为什么Assert.AreEqual(1.0,double.NaN,1.0)通过?

Egi*_*sen 13 .net double assert mstest nan

简短的问题,为什么Assert.AreEqual(1.0, double.NaN, 1.0)通过?而Assert.AreEqual(1.0, double.NaN)失败.

这是MSTest(Microsoft.VisualStudio.QualityTools.UnitTestFramework)中的错误还是我在这里遗漏了什么?

最好的问候,埃吉尔.


更新:应该补充一点,我的问题背后的原因是,由于某些线性代数矩阵运算的结果是NaN或(+/-)Infinity,我有一堆单元测试不幸通过了.单元测试很好,但是由于Assert.AreEqual对带有delta的双精度将在实际或/和预期为NaN或Infinity时通过,我只能相信我测试的代码是正确的.

Mic*_*tta 9

小心.NaN很奇怪,在许多DBMS中有点像null,你不应该将值与它进行比较(直接或与Assert.AreEqual).来自Double.NaN的文档:

使用IsNaN确定值是否不是数字.通过将值与另一个等于NaN的值进行比较,无法确定值是否为数字.

double zero = 0;
Console.WriteLine((0 / zero) == Double.NaN);  // prints false
Console.WriteLine(Double.IsNaN(0 / zero));  // prints true
Run Code Online (Sandbox Code Playgroud)

您必须查看Assert的内部(double,double,double)才能看到正在发生的事情,但总的来说,您依赖于相对于NaN的未定义行为.


Han*_*ant 6

答案已经过时了.如果bug已被修复,何时以及在哪个版本的程序集中?

这是正确的,它在VS2013中使用Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll程序集10.0.0.0版进行了修复.在旧版GAC c:\ windows\assembly中,它还具有10.1.0.0版本.

这里有一个DLL Hell故事,10.1.0.0版本是VS2010中使用的版本.它有错误,没有正确检查Double.NaN.微软犯了一个错误,他们修复了10.1.0.0,但没有改变版本号.因此,安装VS2013 安装VS2010的任何人都会受到伤害,它会用错误的版本覆盖DLL.

解开DLL Hell绝不是那么简单,但是从连接文章和它在我的机器上工作的方式看来,他们从客户的投诉中识别出故障模式.并提供了一个修复程序,在更新中提供.在2014年7月之后不清楚哪个.你现在将使用v10.0.0.0,MSTest.exe测试运行器和QTAgents有一个.config文件,<bindingRedirect>其重定向从10.1.0.0到10.0.0.0(不是拼写错误) .请务必获取当前的最新更新4.如果您不确定已安装的更新,请查看帮助+关于.

为了记录,固定代码获得Double.NaN的特定检查,它看起来像这样:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*kol 5

MSTest对该Assert.AreEqual<double>(expected, actual, delta)方法使用以下公式:

if (Math.Abs(expected - actual) > delta)
    Assert.HandleFail("Assert.AreEqual", ...)
Run Code Online (Sandbox Code Playgroud)

操作减少到double.NaN > delta,在这种情况下返回true.或者未定义.