Python unittesting: Test whether two angles are almost equal

python, python-unittest, unit-testing

Solution

You can use the squared Euclidian distance between two points on the unit circle and the law of cosines to get the absolute difference between two angles:

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)

This works with radians. If the angle is in degrees, you must do a conversion:

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)

Problem

I want to test a function that outputs a heading in degrees, which is a number in the interval [0, 360). Since the result is a floating-point number, comparing the actual result against the expected with `unittest.assertEqual()` does not work. `unittest.assertAlmostEqual()` is better since it provides a tolerance. This approach works for heading that are not close to 0 degrees. Question: What is the correct way to test for headings whose expected value is 0 degrees? `assertAlmostEquals()` would only include angles that are slightly larger than 0 degrees, but would miss those that are slightly smaller than 0, i.e. 360 degrees...

Original source