2009-11-22 21 views
13

Pregunta breve, ¿por qué pasa Assert.AreEqual(1.0, double.NaN, 1.0)? Mientras que Assert.AreEqual(1.0, double.NaN) falla.¿Por qué pasa Assert.AreEqual (1.0, double.NaN, 1.0)?

¿Es un error en MSTest (Microsoft.VisualStudio.QualityTools.UnitTestFramework) o me estoy perdiendo algo aquí?

Saludos, Egil.


Actualización: probablemente habría que añadir, que la razón de mi pregunta es, que tengo un montón de pruebas unitarias que lamentablemente falleció debido al resultado de alguna operación de matriz algebraica lineal es NaN o (+/-) Infinito. Las pruebas unitarias están bien, pero como Assert.AreEqual en dobles con un delta pasará cuando real o esperado sea NaN o Infinity, me dejaron creer que el código que estaba probando era correcto.

+1

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

+0

Y los idiotas lo cerraron como "por diseño". –

+0

Interesante, porque MS se retractó y dice que ahora está arreglado: http://connect.microsoft.com/VisualStudio/feedback/details/780654/assert-equal-and-double-nan – Pat

Respuesta

9

Ten cuidado. NaN es extraño, algo así como nulo en muchos DBMS, y no debería comparar valores con él (ya sea directamente o con Assert.AreEqual). A partir de los documentos de Double.NaN:

Uso isNaN para determinar si un valor no es un número. No es posible determinar si un valor no es un número comparándolo con otro valor igual a NaN.

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

Habría que mirar a la parte interna de Assert (doble, doble, doble) para ver lo que está pasando, pero, en general, que está en función de un comportamiento no definido en relación con NaN.

+0

La historia detrás de mi pregunta es un conjunto de pruebas unitarias que desafortunadamente pasaron debido al resultado de una operación de matriz algebraica lineal que es NaN/(+/-) Infinito. Las pruebas unitarias están bien, pero dado que Assert.AreEqual en dobles con un delta pasará cuando real o esperado sea NaN o Infinity, me dejaron creer que mi código realmente funcionó ... –

+1

Lo entiendo. A primera vista, el comportamiento es incorrecto y estaría justificado que presente un problema en Microsoft Connect. Si lo desea, conecte un servidor de símbolos y vea cómo Assert.AreEqual (doble, doble) difiere de Assert.AreEqual (doble, doble, doble). –

5

MSTest utiliza la siguiente fórmula para el método Assert.AreEqual<double>(expected, actual, delta):

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

La operación se reduce a double.NaN > delta, que devuelve cierto en este caso. O indefinido

6

Las respuestas están desactualizadas. Si el error se ha solucionado, ¿cuándo y en qué versiones de qué ensamblaje?

Eso es correcto, que se fijó en VS2013 con el conjunto Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll, versión 10.0.0.0. Presente en el legado GAC, c: \ windows \ assembly, también tiene la versión 10.1.0.0.

hay una historia DLL Infierno aquí, la versión 10.1.0.0 fue la utilizada en VS2010. Tenía el error, no se buscaba correctamente para Double.NaN. Microsoft cometió un error, corrigieron 10.1.0.0 pero no cambiaron el número de versión. Así que cualquiera que instaló VS2010 después de instalar VS2013 va a salir herido, que va a sobrescribir el archivo DLL con la versión buggy.

Desenredar DLL Infierno nunca es tan simple, pero se desprende de la connect article y de la forma en que funciona en mi máquina que identifican el modo de fallo de la queja del cliente. Y proporcionó una solución, entregada en una actualización. No está claro que, después de julio de 2014. Ahora vamos a utilizar v10.0.0.0, el corredor de prueba MSTest.exe y los QTAgents tienen un archivo .config con un <bindingRedirect> que redirige desde 10.1.0.0 a 10.0.0.0 (no es un error) Asegúrese de obtener la última actualización, actualmente 4. Mire en Ayuda + Acerca de si no está seguro de qué actualización ha instalado.

Para el registro, el código de uso adquiridos controles específicos para Double.NaN, que se ve así:

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

Gracias Hans, completo como siempre. The 'dll hell' explica las inconsistencias en la reproducción de este error entre las máquinas de mis colegas. –