2015-10-18 237 views
4

比方說,我寫的是返回一個浮點數的功能單元測試,我可以做到這樣全精度按我的機器:如何執行浮點輸出的單元測試? - 蟒蛇

>>> import unittest 
>>> def div(x,y): return x/float(y) 
... 
>>> 
>>> class Testdiv(unittest.TestCase): 
...  def testdiv(self): 
...    assert div(1,9) == 0.1111111111111111 
... 
>>> unittest.main() 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 

將在相同的全浮點精度在OS /發行版/機器上是否一樣?

我可以嘗試四捨五入,做單元測試這樣:

>>> class Testdiv(unittest.TestCase): 
...  def testdiv(self): 
...    assert round(div(1,9),4) == 0.1111 
... 
>>> 

我也可以做一個斷言與log(output)但爲了保持一個固定小數精度,我仍然需要做倒圓或截斷。

但是,還有什麼其他的方式應該pythonically處理浮點輸出的單元測試?

回答

5

Python中的float的精度取決於底層的C表示。從Tutorial/Floating Point Arithmetic: Issues and Limitations, 15.1

今天,幾乎所有的機器(2000年11月)使用IEEE-754的浮點運算 ,幾乎所有的平臺的Python映射浮IEEE-754 「雙精度」。


至於測試,更好的想法是使用現有的功能,例如TestCase.assertAmostEqual

assertAlmostEqual(第一,第二,地點= 7,味精=無,增量=無)

測試該第一近似(或不近似) 等於通過計算差值,四捨五入到給定數 十進制地方(默認值爲7),並比較爲零。如果增量代替供給的地方然後第一之間的差必須是(或大於)小於或等於增量

例子:

import unittest 

def div(x, y): return x/float(y) 

class Testdiv(unittest.TestCase): 
    def testdiv(self): 
     self.assertAlmostEqual(div(1, 9), 0.1111111111111111) 
     self.assertAlmostEqual(div(1, 9), 0.1111, places=4) 

unittest.main() # OK 

如果你願意堅持assert聲明,你可以使用math.isclose(Python的3.5+):

import unittest, math 

def div(x, y): return x/float(y) 

class Testdiv(unittest.TestCase): 
    def testdiv(self): 
     assert math.isclose(div(1, 9), 0.1111111111111111) 

unittest.main() # OK 

math.close默認相對容差爲1E -09,「,確保這兩個值在大約9位十進制數字內相同。」。有關math.close的更多信息,請參閱PEP 485

3

unittest.TestCase類具有比較浮點數的具體方法:assertAlmostEqualassertNotAlmostEqual。引用的文件:

assertAlmostEqual第一,第二,地點= 7,味精=無,增量=無assertNotAlmostEqual第一,第二,地點= 7,MSG =無δ=無

測試該第一近似(或不近似) 通過計算差等於舍入給定數 十進制地方(默認7),並比較爲零。請注意,這些方法將數值四捨五入爲給定數小數位(即 ,如round()函數),而不是有效數字

如果增量代之以供給 第一之間的地方則差值第二必須爲(或大於)小於或等於增量

因此,可以測試這樣的功能:

self.assertAlmostEqual(div(1, 9), 0.1111111111111111) # round(a-b, 7) == 0 
self.assertAlmostEqual(div(1, 9), 0.1111, 4)   # round(a-b, 4) == 0 

使用TestCase.assert*方法優於裸assert語句,因爲後者在某些情況下被優化了。此外,這些方法產生的測試失敗消息通常更具信息性。