【问题标题】:How do I use Intellitest to test floating point output?如何使用 Intellitetest 测试浮点输出?
【发布时间】:2016-04-23 16:46:28
【问题描述】:

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

我了解 Intellitet 在浮点测试方面存在限制。我该如何解决这些问题,最好不要完全跳出框架?我在其余代码中成功使用了它,所以我想找到一个尽可能匹配相同方法的解决方法。

我在一个类上有两个属性:

public double CutLengthInInches
{
    get;
    set;
}

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

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

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

当我运行它时,Intellitet 报错:

分支条件涉及以下操作:

floating point equality

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    例如如果您选择double.Epsilon 作为您的容差,则更新比较如下:(Math.Abs(value - target.CutLengthInMM) < double.Epsilon)

    现在,来到 IntelliTest: 当 IntelliTest 观察到代码进行如此精确的比较时,它会用可测试性警告标记它们。 继续使用上述容差值,更新您的断言如下:

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

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

    【讨论】:

    • 谢谢 - 这很有帮助!我不得不使用比 Epsilon 大得多的值,但原理很好。代码覆盖率现在看起来不错。
    猜你喜欢
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2022-09-27
    • 2021-12-01
    • 2017-04-30
    • 1970-01-01
    相关资源
    最近更新 更多