0

测试不等于精确值的最佳方法是什么,例如大圆计算:

/// <summary>
///  Get the great circle distance (shortest distance possible) between two points in km.
/// </summary>
/// <param name="endPoint">end point</param>
/// <returns>the great circle distance in km</returns>
public double GreatCircleDistanceInKm(IGeoPoint endPoint)
{
    var earthRadius = Constants.EARTH_RADIUS_KM;
    var diffLat = Utility.DegreesToRadians(endPoint.Latitude - this.Latitude);
    var diffLong = Utility.DegreesToRadians(endPoint.Longitude - this.Longitude);

    var a = Math.Sin(diffLat / 2) * Math.Sin(diffLat / 2) +
            Math.Cos(Utility.DegreesToRadians(this.Latitude)) * Math.Cos(Utility.DegreesToRadians(endPoint.Latitude)) *
            Math.Sin(diffLong / 2) * Math.Sin(diffLong / 2);
    var c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
    var d = earthRadius * c;

    return d;
}

目前我的测试是这样的:

[TestMethod]
public void GeoPoint_GreatCircleDistanceInKm_IsCorrect()
{
    // arrange
    var startPoint = new GeoPoint(0, 45, 90); // id, lat, long
    var endPoint1 = new GeoPoint(0, 45, 90);
    var endPoint2 = new GeoPoint(0, 0, 0);

    // act
    var greatCircleDistanceZero = startPoint.GreatCircleDistanceInKm(endPoint1);
    var greatCircleDistanceBig = startPoint.GreatCircleDistanceInKm(endPoint2);

    // assert
    Assert.AreEqual(0, greatCircleDistanceZero);
    Assert.AreEqual(10007.543398010288, greatCircleDistanceBig);
}

但这似乎是错误的,我首先找到答案然后对其进行测试。应该如何测试这些方法?我是否应该通过算法/计算并尝试找出它是如何工作的,以便我可以让它产生精确的值?

澄清: 我的问题是这是对此类事物进行测试的正确方法,即。我的测试应该绑定到实际的实现(因为如您所见,我使用的是细粒度的期望值)还是应该以某种方式更通用?

4

3 回答 3

1

您可以使用Assert.AreEqual(double expected, double actual, double delta). 您应该使用足够小的增量(例如 0.00000001)。此处不推荐使用 double.Epsilon。

来自 MSDN:

因为 Epsilon 定义了范围接近于零的正值的最小表达式,所以两个相似值之间的差异幅度必须大于 Epsilon。通常,它比 Epsilon 大很多倍。因此,我们建议您在比较 Double 值是否相等时不要使用 Epsilon。

对于您的其他问题:是的,应该测试这些方法。但是在检查了算法是如何实现的之后编写测试并不是一个好主意,因为它可能实现错误。您需要一个整体的想法,例如该方法应该做什么(在您的情况下计算大圆距离)。现在您可以通过指定输入和预期输出来指定测试用例。您可以从另一个来源检索预期的输出(例如手动计算)。

一点旁注:在 TDD 中,测试用例通常是在编写实际代码之前指定的。因此,没有一种算法可以让您通过并找出它是如何工作的。

于 2014-12-19T12:15:42.170 回答
0

也许

Assert.IsTrue(Math.Abs(greatCircleDistanceZero - 0) < Double.Epsilon);
Assert.IsTrue(Math.Abs(greatCircleDistanceBig - 10007.543398010288) < Double.Epsilon);
于 2014-12-19T12:08:20.387 回答
0

下表显示了赤道上两点之间的距离。随着纬度从两极移开,NS 距离是恒定的,但 EW 距离会减小。正如我假设使用大圆距离,结果中任何大于 2 位小数的精度都是多余的。

0 decimal places    1.0  = 111.32 km  
1 decimal places    0.1 = 11.132 km 
2 decimal places    0.01 = 1.1132 km 
3 decimal places    0.001 = 111.32 m 
4 decimal places    0.0001 = 11.132 m   
5 decimal places    0.00001 = 1.1132 m 
于 2014-12-19T18:21:06.443 回答