2010-03-26 80 views
6

爲什麼我會得到這個結果?double.NaN平等在MS測試

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

三角洲聲稱NaN有什麼區別等於一個數字?當然,它總是會返回錯誤的。我知道IsNaN,但在這裏沒有用(見下文)。背景:我有一個函數返回NaN(錯誤地),它的意思是一個實數,但測試仍然通過。我使用的是三角洲,因爲它是雙精度平等,原始測試使用1E-9。

+2

Microsoft bug entry:https://connect.microsoft.com/VisualStudio/feedback/details/762286/unit-test-with-assert-areequal-2-3-double-nan-0-1-passes – jbe 2012-09-12 09:29:09

+0

請參閱也是http://stackoverflow.com/questions/1780004/why-do-mstests-assert-areequal1-0-double-nan-0-0-pass – 2015-01-20 11:30:58

回答

3

當您使用Assert.AreEqual(1, double.NaN),它試圖相等測試在數字上,當然它失敗了,因爲double.NaN不等於任何東西。

當你做Assert.AreEqual(1, double.NaN, 1E-1),它必須對數字進行算術運算。具體來說,它計算

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 !=) 

這是錯誤的。它看起來像實際增量不大於你通過的delta,但只是因爲它試圖表明你不能執行比較。這個故事的寓意:NaN的行爲非常瘋狂(但最好的一些聰明的人可以提出)。在執行任何計算之前,儘可能檢查NaN,在這種情況下,您無法默默地傳播錯誤,就像這樣。

+0

很好的解釋,謝謝 – RichK 2010-03-26 15:54:01

1

你可以用NaN代替這個測試嗎?

double.IsNaN(somenNumber) 
+1

是的,但我不希望我的結果是NaN,如果我只是運行測試而沒有用期望的值進行調試,它會通過。不好。 – RichK 2010-03-26 15:45:19

1

看一看這裏:Why does Assert.AreEqual(1.0, double.NaN, 1.0) pass?

編輯:

肯定是有在Assert.AreEqual的錯誤。在VS 2008的Microsoft.VisualStudio.QualityTools.UnitTestFramework它的編碼爲

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

至於你的情況Math.Abs((double) (expected - actual))double.NaN,比較收益率false :-)

+0

非常好,謝謝。這個問題的OP似乎讓問題與我完全一樣,很奇怪。 – RichK 2010-03-26 15:44:39