简体   繁体   English

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

[英]How do I use Intellitest to test floating point output?

I'm fairly new to Intellitest in VS 2015 (and unit tests in general), and I'm trying to use it to test a simple method that converts between inches and mm. 我在VS 2015(和一般的单元测试)中对Intellitest还是很陌生,我正在尝试使用它来测试一种在英寸和mm之间转换的简单方法。

I understand that Intellitest has limitations around floating point tests. 我了解Intellitest在浮点测试方面存在局限性。 How do I work around these, ideally without stepping completely outside the framework? 我应该如何解决这些问题,理想情况下是不完全脱离框架? I'm using it successfully for the rest of the code, so I'd like to find a workaround that matches the same approach as much as possible. 我在其余的代码中都成功地使用了它,因此我想找到一种解决方法,该解决方法尽可能地与相同的方法匹配。

I have two properties on a class: 我在一个类中有两个属性:

public double CutLengthInInches
{
    get;
    set;
}

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

I then use Intellitest to create a stub, which I fill out as follows: 然后,我使用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);
}

When I run this, Intellitest complains with an error: 当我运行此命令时,Intellitest会报错:

The following operation was involved in a branch condition: 分支条件中涉及以下操作:

 floating point equality 

This operation causes testability problems, and inputs cannot be generated to cover the code following the call. 此操作导致可测试性问题,并且无法生成输入来覆盖调用后的代码。

The line it points to is the first AreEqual() call. 它指向的行是第一个AreEqual()调用。 What's the tidiest workaround to this? 最整齐的解决方法是什么?

Your assertion is doing an exact comparison between floating point values. 您的断言是在浮点值之间进行精确比较。 You should avoid such comparison regardless of whether you are using IntelliTest. 无论是否使用IntelliTest,都应避免这种比较。 It is unsafe for applications to rely on exact floating-point comparisons; 应用程序依靠精确的浮点比较是不安全的。 slight variations in rounding can change the outcome of such comparisons, leading to unexpected behavior (for eg test case failures!). 四舍五入的微小变化会改变这种比较的结果,从而导致意外行为(例如,测试用例失败!)。

Instead, tests for equality of floating-point quantities should be made within some tolerance related to the expected precision of the calculation (ie compare whether the values are "equal enough"). 取而代之的是,应在与计算的预期精度有关的一定公差范围内进行浮点数相等性的测试(即比较值是否“足够相等”)。

For eg if you go with double.Epsilon as your tolerance, then update the comparison like so: (Math.Abs(value - target.CutLengthInMM) < double.Epsilon) . 例如,如果您使用double.Epsilon作为公差, double.Epsilon如下方式更新比较: (Math.Abs(value - target.CutLengthInMM) < double.Epsilon)

Now, coming to IntelliTest: When IntelliTest observes code doing such exact comparisons it flags them with the Testability warning. 现在,进入IntelliTest:当IntelliTest观察到代码在进行如此精确的比较时,它会用Testability警告对其进行标记。 Continuing with above tolerance value, update your assertion as follows: 继续上述公差值,如下更新您的断言:

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

You will see a warning that the call to Math.Abs was uninstrumented. 您将看到一条警告, Math.Abs未对Math.Abs的调用。 That is OK (since we are not interested in testing that method). 可以(因为我们对测试该方法不感兴趣)。 After ensuring that you have addressed any other such issues, you can select the warning and Suppress it (by clicking on the Suppress button on the Exploration Results window's toolbar). 确保解决了其他任何此类问题后,可以选择警告并予以抑制(通过单击“勘探结果”窗口的工具栏上的“抑制”按钮)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM