如何使用Intellitest测试浮点输出?

时间:2016-04-23 16:46:28

标签: c# unit-testing visual-studio-2015 intellitest

我对VS 2015中的Intellitest相当新(以及一般的单元测试),我试图用它来测试一种在英寸和毫米之间转换的简单方法。

据我所知,Intellitest在浮点测试方面存在局限性。我如何解决这些问题,理想情况下不会完全脱离框架?我已成功将其用于其余代码,因此我希望找到一种尽可能匹配相同方法的解决方法。

我在课堂上有两个属性:

public double CutLengthInInches
{
    get;
    set;
}

public double CutLengthInMM
{
    get
    {
        return CutLengthInInches * 25.4;
    }
    set
    {
        CutLengthInInches = value / 25.4;
    }
}

然后我使用Intellitest创建一个存根,我填写如下:

[PexMethod]
public void CutLengthInMMSet([PexAssumeUnderTest]CutPiece target, double value)
{
    target.CutLengthInMM = value;
    PexAssert.AreEqual(value, target.CutLengthInMM);
    PexAssert.AreEqual(value, target.CutLengthInInches * 25.4);
}

当我运行时,Intellitest抱怨错误:

  

以下操作涉及分支条件:

floating point equality
     

此操作会导致可测试性问题,并且输入不能   生成以覆盖通话后的代码。

它指向的行是第一个AreEqual()调用。什么是最整洁的解决方法?

1 个答案:

答案 0 :(得分:0)

您的断言正在对浮点值进行精确比较。无论您使用的是IntelliTest,都应该避免这种比较。应用程序依赖于精确的浮点比较是不安全的;舍入的微小变化可能会改变这种比较的结果,从而导致意外行为(例如测试用例失败!)。

相反,浮点数量相等的测试应该在与计算的预期精度相关的某个容差范围内进行(即比较值是否“足够”)。

例如如果您使用double.Epsilon作为容差,请更新比较,如下所示:(Math.Abs(value - target.CutLengthInMM) < double.Epsilon)

现在,来到IntelliTest: 当IntelliTest观察到执行此类精确比较的代码时,它会使用Testability警告标记它们。 继续使用上述容差值,按如下方式更新断言:

PexAssert.IsTrue(Math.Abs(value - target.CutLengthInMM) < double.Epsilon);

您会看到一条警告,表示对Math.Abs的调用未经检测。这没关系(因为我们对测试该方法不感兴趣)。确保已解决任何其他此类问题后,您可以选择警告并将其取消(通过单击“探索结果”窗口工具栏上的“抑制”按钮)。