2009-11-22 3 views
13

Domanda breve, perché passa Assert.AreEqual(1.0, double.NaN, 1.0)? Considerando che Assert.AreEqual(1.0, double.NaN) non riesce.Perché Assert.AreEqual (1.0, double.NaN, 1.0) passa?

Si tratta di un bug in MSTest (Microsoft.VisualStudio.QualityTools.UnitTestFramework) o mi manca qualcosa qui?

Cordiali saluti, Egil.


Aggiornamento: dovrebbe probabilmente aggiungere, che il motivo dietro la mia domanda è, che ho un po 'di test di unità che purtroppo passati per effetto del risultato di alcune operazioni di matrice algebrici lineari essere NaN o (+/-) Infinito. I test unitari vanno bene, ma poiché Assert.AreEqual sui doppi con un delta passerà quando effettivo o/e previsto sono NaN o Infinity, mi è stato lasciato credere che il codice che stavo testando fosse corretto.

+1

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

+0

E gli idioti lo hanno chiuso come "design". –

+0

Interessante, perché MS ritrattato e dice che è stato risolto: http://connect.microsoft.com/VisualStudio/feedback/details/780654/assert-equal-and-double-nan – Pat

risposta

9

Fare attenzione. NaN è strano, un po 'come null in molti DBMS, e non dovresti confrontare i valori con esso (direttamente o con Assert.AreEqual). Dalla documentazione per Double.NaN:

Usa isNaN per determinare se un valore non è un numero. Non è possibile stabilire se un valore non è un numero confrontandolo con un altro valore uguale a NaN.

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

Avresti per scrutare la struttura interna di Assert (doppio, doppio, doppio) per vedere cosa sta succedendo, ma in generale, si sta a seconda indefinito comportamento relativo alla NaN.

+0

La storia dietro la mia domanda è un gruppo di test unitari che sfortunatamente sono passati a causa del risultato di un'operazione di matrice algebrica lineare come NaN/(+/-) Infinity. I test unitari vanno bene, ma poiché Assert.AreEqual su double con un delta passerà quando effettivo o/e previsto sono NaN o Infinity, mi è stato lasciato credere che il mio codice funzionasse davvero ... –

+1

Lo capisco. A prima vista, il comportamento non è corretto e sarebbe giustificato presentare un problema su Microsoft Connect. Se lo desideri, aggancia un server di simboli e osserva come Assert.AreEqual (double, double) si differenzia da Assert.AreEqual (double, double, double). –

5

MSTest utilizza la seguente formula per il metodo Assert.AreEqual<double>(expected, actual, delta):

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

L'operazione riduce a double.NaN > delta, che restituisce vero in questo caso. O indefinito.

6

Le risposte non sono aggiornate. Se il bug è stato corretto, quando e in quali versioni di quale assembly?

Questo è corretto, è stato risolto in VS2013 con l'assembly Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll, versione 10.0.0.0. Presente nella versione precedente di GAC, c: \ windows \ assembly, ha anche la versione 10.1.0.0.

C'è una storia di inferno DLL qui, la versione 10.1.0.0 era quella usata in VS2010. Aveva l'errore, non controllando correttamente Double.NaN. Microsoft ha commesso un errore, hanno risolto 10.1.0.0 ma non hanno modificato il numero di versione. Quindi chiunque abbia installato VS2010 dopo l'installazione di VS2013 si farà male, sta per sovrascrivere la DLL con la versione buggata.

Unraveling DLL L'inferno non è mai così semplice, ma viene visualizzato dal e dal modo in cui funziona sulla mia macchina che hanno identificato la modalità di errore dal reclamo del cliente. E ha fornito una correzione, consegnata in un aggiornamento. Non chiaro quale, dopo luglio 2014. Ora utilizzerai v10.0.0.0, il test runner MSTest.exe e QTAgents hanno un file .config con un <bindingRedirect> che reindirizza da 10.1.0.0 a 10.0.0.0 (non è un errore di battitura). Assicurati di ottenere l'ultimo aggiornamento, attualmente 4. Cerca in Aiuto + Informazioni se non sei sicuro di quale aggiornamento hai installato.

Per la cronaca, il codice fisso acquistato controlli specifici per Double.NaN, sembra che questo:

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); 
    } 
} 
+1

Grazie Hans, accurato come sempre. Il "diavolo inferno" spiega le incongruenze nel riprodurre questo insetto tra le macchine dei miei colleghi. –