2010-03-26 2 views
6

Warum bekomme ich dieses Ergebnis?double.NaN Gleichheit in MS Test

[TestMethod] 
public void nan_test() 
{ 
    Assert.AreEqual(1, double.NaN, 1E-1); <-- Passes 
    Assert.AreEqual(1, double.NaN);  <-- Fails 
} 

Welchen Unterschied hat das Delta bei der Bestätigung von NaN gleich einer Zahl? Sicher sollte es immer falsch zurückgeben. Ich kenne IsNaN, aber das ist hier nicht sinnvoll (siehe unten).

Hintergrund: Ich habe eine Funktion, die NaN (fehlerhaft) zurückgibt, es sollte eine reelle Zahl sein, aber der Test ist noch bestanden. Ich benutze das Delta, weil es doppelte Genauigkeitsgleichheit ist, der ursprüngliche Test verwendete 1E-9.

+2

Eintrag Microsoft Bug: https://connect.microsoft.com/VisualStudio/feedback/details/762286/unit-test-with-assert-areequal-2-3-double-nan-0-1-passes – jbe

+0

anzeigen auch http://stackoverflow.com/questions/1780004/why-do-mstests-assert-areequal1-0-double-nan-0-0-pass –

Antwort

3

Wenn Sie Assert.AreEqual(1, double.NaN), versucht er, einen Gleichheitstest auf die Zahlen und natürlich scheitert es, da double.NaN nichts ist.

Wenn Sie Assert.AreEqual(1, double.NaN, 1E-1) tun, muss es Arithmetik auf den Zahlen tun. Insbesondere berechnet es

Math.Abs((double) (expected - actual)) > delta 
Math.Abs(1 - double.NaN) > 1E-1 
Math.Abs(double.NaN) > 1E-1 // All arithmetic with double.NaN returns double.NaN 
double.NaN > 1E-1 // All comparisons with double.NaN return false (except !=) 

was falsch ist. Es sieht wie das tatsächliche Delta ist nicht größer als die delta Sie bestanden, aber nur, weil es versucht zu zeigen, dass Sie den Vergleich nicht durchführen können.

Moral der Geschichte: das Verhalten von NaN ist ziemlich verrückt (aber das Beste, was einige kluge Leute finden könnten). Tun Sie Ihr Bestes, um nach NaN zu suchen, bevor Sie irgendwelche Berechnungen durchführen, bei denen Sie den Fehler nicht wie bei diesem ruhig ausbreiten lassen können.

+0

Gute Erklärung, danke – RichK

1

Könnten Sie diesen Test stattdessen für NaN verwenden?

double.IsNaN(somenNumber) 
+1

Ja, aber ich will nicht mein Ergebnis NaN sein, wenn ich führte den Test nur ohne Debugging mit einem erwarteten Wert durch, es würde bestehen. Nicht gut. – RichK

1

Werfen Sie einen Blick hier: Why does Assert.AreEqual(1.0, double.NaN, 1.0) pass?

Edit:

es auf jeden Fall einen Fehler in Assert.AreEqual ist. in VS 2008 ist Microsoft.VisualStudio.QualityTools.UnitTestFramework ist es codiert als

if (Math.Abs((double) (expected - actual)) > delta) 
{ 
    // report error 
} 

Wie in Ihrem Fall Math.Abs((double) (expected - actual)) ein double.NaN ist der Vergleich Ausbeuten false :-)

+0

Ausgezeichnet, danke. Der OP dieser Frage scheint das Problem zu haben, genau dasselbe wie ich zu tun, komisch. – RichK