浮動小数点数を返す関数の単体テストを書いているとしましょう。私のマシンのように、完全な精度でそれを行うことができます。
_>>> 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)
を使用してアサートを実行することもできますが、小数点以下の精度を維持するには、丸めまたは切り捨てを行う必要があります。
しかし、浮動小数点出力のユニットテストをPythonで処理する他の方法は何ですか?
Python=のfloat
の精度は、基になるCの表現に依存します。From Tutorial/Floating Point Arithmetic:Issues and Limitations、15.1 :
今日のほとんどすべてのマシン(2000年11月)はIEEE-754浮動小数点演算を使用しており、ほとんどすべてのプラットフォームがPython floatsをIEEE-754「倍精度」にマップします。
テストに関しては、既存の機能を使用することをお勧めします。 TestCase.assertAmostEqual
:
assertAlmostEqual(first、second、Places = 7、msg = None、delta = None)
first と second がほぼ等しい(またはほぼ等しくない)であることをテストするために、差を計算し、指定された小数に丸めます places (デフォルトは7)、ゼロと比較します。 places の代わりに delta が指定されている場合、 first と second は、 delta 以下でなければなりません。
例:
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、 "です。これにより、2つの値が約9桁の10進数内で同じになります。" 。 math.close
の詳細については、 PEP 485 を参照してください。
unittest.TestCase
クラスには、フロートを比較するための特定のメソッドがあります: assertAlmostEqual
および assertNotAlmostEqual
。ドキュメントを引用するには:
assertAlmostEqual(first、second、Places = 7、msg = None、delta = None) assertNotAlmostEqual(first、second、Places = 7、msg = None、delta = None)
firstとsecondが、差を計算し、与えられた値に丸めることにより、ほぼ等しい(またはほぼ等しくない)ことをテスト10進数の数places(デフォルトは7)、ゼロとの比較。これらのメソッドは、値を所定の数のdecimal placesに丸めます(つまり、
round()
関数のように)。有効数字。placesの代わりにdeltaが指定されている場合、first /の違いおよびsecondは、delta以下でなければなりません。
したがって、次のように関数をテストできます。
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
余談ですが、テストランナーとしてpytest
を使用しない限り、メソッドによって生成されるテスト失敗メッセージは一般的にはるかに有益であるため、TestCase.assert*
メソッドをassert
ステートメントよりも優先する必要があります。