Почему передает Assert.AreEqual(1.0, double.NaN, 1.0)?

Короткий вопрос, почему проходит Assert.AreEqual(1.0, double.NaN, 1.0)? В то время как Assert.AreEqual(1.0, double.NaN) терпит неудачу.

Является ли это ошибкой в ​​MSTest (Microsoft.VisualStudio.QualityTools.UnitTestFramework) или мне что-то не хватает?

С наилучшими пожеланиями, Эгил.


Обновление. Возможно, следует добавить, что причина моего вопроса заключается в том, что у меня есть куча модульных тестов, которые, к сожалению, прошли из-за результата какой-либо операции линейной алгебраической матрицы, являющейся NaN или (+/-) Infinity. Единичные тесты являются точными, но поскольку Assert.AreEqual на удвоениях с дельтами будет проходить, когда фактические или ожидаемые будут NaN или Infinity, мне оставалось полагать, что код, который я тестировал, был правильным.

Ответы

Ответ 1

Будьте осторожны. NaN является странным, несколько нулевым во многих СУБД, и вам не следует сравнивать значения с ним (либо напрямую, либо с помощью 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), чтобы увидеть, что происходит, но в целом вы зависите от поведения undefined относительно NaN.

Ответ 2

Ответы устарели. Если ошибка была исправлена, когда и в каких версиях какой сборки?

Правильно, он был исправлен в 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. Microsoft допустила ошибку, они исправили 10.1.0.0, но не изменили номер версии. Таким образом, любой, кто установил VS2010 после установки VS2013, будет поврежден, он перезапишет DLL с ошибкой версии.

Unraveling DLL Hell никогда не бывает таким простым, но из соединить статью и с тем, как она работает на моей машине, они идентифицировали отказ от жалобы клиента. И предоставил исправление, поставленное в обновлении. Непонятно, что после июля 2014 года. Теперь вы будете использовать v10.0.0.0, тестовый бегун MSTest.exe, а QTAgents - файл .config с <bindingRedirect>, который перенаправляет с 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);
    }
}

Ответ 3

MSTest использует следующую формулу для метода Assert.AreEqual<double>(expected, actual, delta):

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

Операция сводится к double.NaN > delta, которая возвращает true в этом случае. Или undefined.