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 は範囲がゼロに近い正の値の最小式を定義するため、2 つの類似した値の差のマージンは Epsilon よりも大きくなければなりません。通常、これは Epsilon の何倍も大きくなります。このため、Double 値が等しいかどうかを比較する場合は、Epsilon を使用しないことをお勧めします。

他の質問に対して: はい、そのような方法はテストする必要があります。しかし、アルゴリズムがどのように実装されているかを調べた後でテストを書くのは良い考えではありません。実装が間違っている可能性があるからです。たとえば、メソッドが何をすべきか全体的なアイデアが必要です(あなたの場合、大円距離を計算しています)。入力と期待される出力を指定することで、テスト ケースを指定できるようになりました。予想される出力を別のソースから取得できます (たとえば、手で計算するなど)。

ちょっとした補足: TDD では、通常、実際のコードを記述する前にテスト ケースが指定されます。したがって、それがどのように機能するかを調べることができるアルゴリズムはありません。

于 2014-12-19T12:15:42.170 に答える
0

Maybe

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