2014-12-02 93 views
2

我想测试一个输出以度数为单位的标题的函数,该函数是区间[0,360)中的一个数字。由于结果是浮点数,因此将实际结果与unittest.assertEqual()的预期结果进行比较是行不通的。 unittest.assertAlmostEqual()更好,因为它提供了一个容差。这种方法适用于不接近0度的航向。Python单元测试:测试两个角度是否几乎相等

问题:测试期望值为0度的标题的正确方法是什么? assertAlmostEquals()只包含略大于0度的角度,但会错过略小于0的角度,即360度...

+0

定义自己的辅助函数,它有两个角,并返回ABS的区别 – matcheek 2014-12-02 17:17:06

+0

的每当你比较浮点数,你必须包括一个“ epsilon',一个小数字,低于该数字的所有意图和目的被认为是零。例如:1E-6或1E-8等'a == b如果abs(a - b)<= epsilon。如果两个值接近0,事情就会变得棘手。 – Pierre 2014-12-02 17:43:36

回答

4

您可以使用单位圆上两点之间的平方欧氏距离和以获得两个角度之间的绝对差值:

from math import sin, cos, acos 
from unittest import assertAlmostEqual   

def assertAlmostEqualAngles(x, y, **kwargs): 
    c2 = (sin(x)-sin(y))**2 + (cos(x)-cos(y))**2 
    angle_diff = acos((2.0 - c2)/2.0) # a = b = 1 
    assertAlmostEqual(angle_diff, 0.0, **kwargs) 

这适用于弧度。如果角度为度,你必须做一个转换:

from math import sin, cos, acos, radians, degrees 
from unittest import assertAlmostEqual   

def assertAlmostEqualAngles(x, y, **kwargs): 
    x,y = radians(x),radians(y) 
    c2 = (sin(x)-sin(y))**2 + (cos(x)-cos(y))**2 
    angle_diff = degrees(acos((2.0 - c2)/2.0)) 
    assertAlmostEqual(angle_diff, 0.0, **kwargs) 
+0

我不认为这样可以很好地保留角度之间的差异。 – simonzack 2014-12-02 17:25:32

+0

@SturlaMolden这个概念有两个修改:(1)比较sin和cos的结果时,应该设置一个容差;我最终使用了'delta = 0.001'。 (2)如果以度数提供输入,则必须用'x = math.radians(x)'将其转换为弧度。 – ThS 2014-12-02 22:04:53

+0

我已经增加了使用余弦定律的数值校正,并且还有** kwargs将关键字参数的位置,msg和delta传递给assertAlmostEqual。 – 2014-12-03 00:18:47