【问题标题】:Visual studio 2008 unit test keeps failingVisual Studio 2008 单元测试一直失败
【发布时间】:2010-04-23 13:01:25
【问题描述】:

我创建了一种基于双精度列表计算调和平均值的方法。 但是当我运行测试时,即使输出结果相同,它也会一直失败。

我的调和平均法:

public static double GetHarmonicMean(List<double> parameters)
{
    var cumReciprocal = 0.0d;
    var countN = parameters.Count;

    foreach( var param in parameters)
    {
        cumReciprocal += 1.0d/param;
    }

    return 1.0d/(cumReciprocal/countN);
}

我的测试方法:

[TestMethod()]
public void GetHarmonicMeanTest()
{
    var parameters = new List<double> { 1.5d, 2.3d, 2.9d, 1.9d, 5.6d };
    const double expected = 2.32432293165495; 
    var actual = OwnFunctions.GetHarmonicMean(parameters);
    Assert.AreEqual(expected, actual);
}

运行测试后显示以下消息:

Assert.AreEqual 失败。预期:。实际:.

对我来说,这两个值都是一样的。

有人可以解释一下吗?还是我做错了什么?

【问题讨论】:

  • 错误消息文本中可能进行了一些舍入。另一方面,您的方法可以使用 Linq:return 1.0d/parameters.Average(d =&gt; 1.0d / d));
  • 太好了,没想到用 linq 做这个。

标签: c# unit-testing


【解决方案1】:

Assert.AreEqual 的双重重载采用“delta”参数以允许双精度不精确。您应该为此参数指定一个较小的值。

【讨论】:

    【解决方案2】:

    你很难说服 GetHarmonicMean 方法准确地返回 2.32432293165495。双精度比 14 位小数精确得多。例如,您的结果可以是:

    2.32432293165495 - your_result = 0.0000000000000000012345... - 这绝对不是零。

    【讨论】:

      【解决方案3】:

      双数值在显示时会进行四舍五入,因此它们显示的数字比其容量限制少几位(以防止出现舍入错误)。虽然这些值看起来相同,但它们实际上并没有完全相同的值。

      您可以计算该值,然后使用往返格式显示它:

      value.ToString("r")
      

      当解析以这种方式创建的文本表示时,可以保证生成与创建它相同的双精度值。你可以把它放在代码中,它会给你一个完全匹配的。

      但是,通常不应比较 double 值是否完全相等,因为您很少遇到这种情况,您实际上想要完全匹配。此外,在这种情况下,对完全匹配的测试也可能不是您真正想要的,因为它取决于保持完全相同的实现。如果您使用不同的算法,则会产生不同的舍入误差,从而产生略微不同的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-17
        • 1970-01-01
        • 2016-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多