14

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

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

最好的问候,埃吉尔。


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

4

3 回答 3

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

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

于 2009-11-22T21:12:30.277 回答
7

答案已过时。如果错误已被修复,何时以及在哪个程序集的哪个版本中?

没错,它已在 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);
    }
}
于 2015-03-09T01:45:13.677 回答
5

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

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

操作归double.NaN > delta约为 ,在这种情况下返回 true。或未定义。

于 2012-02-24T19:21:27.433 回答