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

时间:2009-11-22 21:07:03

标签: .net mstest double assert 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时通过,我只能相信我测试的代码是正确的。

3 个答案:

答案 0 :(得分:9)

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

  

使用IsNaN确定是否有值   不是一个数字。这是不可能的   确定值是否不是a   将数字与另一数字进行比较   值等于NaN。

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

你必须同意Assert的内部(double,double,double)来看看发生了什么,但总的来说,你依赖于相对于NaN的未定义行为。

答案 1 :(得分:6)

  

答案已过时。如果bug已被修复,何时以及哪个版本的汇编?

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

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

解开DLL地狱绝不是那么简单,但它出现在connect article以及它在我的机器上工作的方式,他们从客户的投诉中找出了失败模式。并提供了一个修复程序,在更新中提供。在2014年7月之后不清楚哪个。你现在将使用v10.0.0.0,MSTest.exe测试运行器和QTAgents有一个带有<bindingRedirect>的.config文件,从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);
    }
}

答案 2 :(得分:5)

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

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

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