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

发布于 2024-08-11 16:20:29 字数 410 浏览 4 评论 0原文

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

这是 MSTest (Microsoft.VisualStudio.QualityTools.UnitTestFramework) 中的错误还是我在这里遗漏了一些东西?

最好的问候,埃吉尔。


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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

徒留西风 2024-08-18 16:20:29

当心。 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 的未定义行为。

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.

温柔女人霸气范 2024-08-18 16:20:29

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

没错,它已在 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 文件,其中包含从 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);
    }
}

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:\windows\assembly, 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);
    }
}
骄傲 2024-08-18 16:20:29

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

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

操作简化为 double.NaN > delta,在本例中返回 true。或者未定义。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文