14

短い質問、なぜAssert.AreEqual(1.0, double.NaN, 1.0)合格するのですか?一方、Assert.AreEqual(1.0, double.NaN)失敗します。

これはMSTest(Microsoft.VisualStudio.QualityTools.UnitTestFramework)のバグですか、それともここに何かが欠けていますか?

よろしく、エギル。


更新:おそらく、私の質問の背後にある理由は、NaNまたは(+/-)Infinityである線形代数行列演算の結果のために残念ながら合格した単体テストがたくさんあることです。単体テストは問題ありませんが、実際のまたは/および期待されるがNaNまたはInfinityの場合、デルタを含むdoubleの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地獄の話があります。10.1.0.0バージョンはVS2010で使用されたものでした。Double.NaNを適切にチェックしないというバグがありました。Microsoftは間違いを犯し、10.1.0.0を修正しましたが、バージョン番号は変更しませんでした。したがって、VS2013のインストールにVS2010をインストールした人は誰でも怪我をすることになり、DLLをバグのあるバージョンで上書きすることになります。

DLL Hellを解明することは決して簡単ではありませんが、接続の記事と私のマシンでの動作方法から、顧客の苦情から障害モードを特定したように見えます。そして、アップデートで提供される修正を提供しました。2014年7月以降、どちらを使用するかは明確ではありません。v10.0.0.0を使用するようになり、MSTest.exeテストランナーとQTAgentには、<bindingRedirect>10.1.0.0から10.0.0.0にリダイレクトする.configファイルがあります(タイプミスではありません)。 。必ず最新のアップデート(現在は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 に答える