Unittest(有时)因为浮点不精确而失败

我有一个Vector类,它代表了三维空间中的一个点。 这个向量有一个方法normalize(self, length = 1) ,它将向量向下/向上缩放为length == vec.normalize(length).length

由于浮点数的不精确性,此方法的unit testing有时会失败。 我的问题是,当方法正确实现时,如何确保这个testing不会失败? 有没有可能做到这一点没有testing一个近似值?


附加信息

  def testNormalize(self): vec = Vector(random.random(), random.random(), random.random()) self.assertEqual(vec.normalize(5).length, 5) 

有时会导致AssertionError: 4.999999999999999 != 5AssertionError: 5.000000000000001 != 5

注意 :我知道浮点问题可能在Vector.length属性或Vector.normalize()

1)我怎样才能确保testing工作?

使用assertAlmostEqualassertNotAlmostEqual

从官方文档 :

 assertAlmostEqual(first, second, places=7, msg=None, delta=None) 

通过计算差值,四舍五入到给定的小数位数(默认值7),并将其与零比较,testing第一个和第二个差不多相等。

2)有没有可能testing一个近似值呢?

基本上没有

浮点问题不能被绕过,所以你必须对vec.normalize给出的结果进行“四舍五入”,或者接受一个几乎相等的结果(两者中的每一个都是近似值)。

通过使用浮点值,您接受一个小的不精确度。 因此,您的testing应testing您的计算值是否落在可接受的范围内,如:

 theoreticalValue - epsilon < normalizedValue < theoreticalValue + epsilon 

其中epsilon是一个非常小的值,您定义为可接受的由于浮点不精确性的变化。

一般来说,你不应该声称平等的花车。 相反,确保结果在一定范围内,例如:

 self.assertTrue(abs(vec.normalize(5).length - 5) < 0.001) 

我想有一种可能性是将函数应用于所有input,所有中间计算的结果以及输出都可以用float精确表示的testing用例。

为了显示:

 In [2]: import math In [4]: def norm(x, y): ...: return math.sqrt(x*x + y*y) ...: In [6]: norm(3, 4) == 5 Out[6]: True 

不知道这是多么实际…