Visual Studio 单元测试:为啥在测试相同的浮点值时测试运行不确定?

Posted

技术标签:

【中文标题】Visual Studio 单元测试:为啥在测试相同的浮点值时测试运行不确定?【英文标题】:Visual Studio Unit Test: why test run inconclusive whereas testing same float values?Visual Studio 单元测试:为什么在测试相同的浮点值时测试运行不确定? 【发布时间】:2011-04-16 05:34:15 【问题描述】:

我正在学习 VS 单元测试并尝试了这个:

    [TestMethod()]
    public void calcTest()
    
        double expected = 1.234F; // TODO: Initialize to an appropriate value
        double actual;
        actual = 1.234F;
        Assert.AreEqual(expected, actual);
        Assert.Inconclusive("Verify the correctness of this test method.");
    

运行此测试方法时,它显示不确定 ???为什么?

更新:可以告诉不要比较浮点数,但业务需求就是它们。那么如果我需要比较它们应该怎么做呢?

你的意思是不可能不头痛地测试浮动计算吗?那么,如果测试在财务计算中如此令人头疼,那不做测试不是更好吗?

似乎是 vs 测试框架中的一个巨大的错误或设计缺陷 :) 就像这里所说的那样 http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.assert.inconclusive%28VS.80%29.aspx

表示一个断言不能被证明为真或假。

因为我比较了 2 个相同的文字,所以确定这是真的。

【问题讨论】:

Microsoft 单元测试套件现在还包括用于测试浮点数(和双精度数)的重载方法,方法是传入一个 delta 容差,该容差告诉这些值必须“如何相等”才能通过 (msdn.microsoft.com/en-us/library/ms243456.aspx)。像这样使用:Assert.AreEqual(float expected, float actual, float delta, string failingTestMessage) 【参考方案1】:

呃,因为你说的?

Assert.Inconclusive("Verify the correctness of this test method.");

现在你有了你的AreEqual,你应该可以删除这个Inconclusive

任何 测试期间的失败(不包括您有意处理的异常)通常是终端,但任何 通过 的断言(如此处的 AreEqual)只会保留在运行。所以第一个测试通过了,然后最后一行将其标记为不确定。

【讨论】:

为什么 Assert.Conclusive 不存在?我们不会在这种不确定性是有意义的情况下进行统计测试,这是确定性测试,测试结果将为是或否。 我认为你是对的,但是模板不应该将它作为默认值放在代码 sn-p 中,因为这非常令人困惑。 @user310291 从测试的角度来看,这并不令人困惑。在您编写正确的测试(并删除不确定的部分)或修复要测试的代码之前,所有测试都会失败。【参考方案2】:

即使您删除了Assert.Inconclusive,您仍然可能遇到问题。

您正在测试两个浮点数的相等性,并且通常使用计算值您永远不会让它们完全相同相同。您需要检查实际值是否在预期值的可接受范围内:

Math.Abs(actual - expected) < 0.00001;

例如。

您的Assert.AreEqual(expected, actual); 在这种情况下有效,因为您为两个变量分配了相同的值。

【讨论】:

很好的警告,但在这种情况下,他正在比较从文字初始化的两个变量,所以我期望没问题。但是+1,绝对是一个非常好的提高点! @Marc - 我发现了所以添加了一个注释。 某些十进制数可能不存在准确的浮点表示这一事实不会使它们“模糊”。关于不比较 2 个浮点数是否相等的一般观点很好,但它不适用于这种情况:编译器没有理由为 same float 文字选择不同的 double 表示. 不是这种情况(非常人为的情况),但总的来说:是的,不要比较浮点数。 什么不比较浮动但业务需求需要比较浮动:)【参考方案3】:

那不就是说AreEqual通过了,也就是说它调用了Assert.Inconclusive,导致结果没有定论?

来自the docs:

类似于失败,因为它表明 一个断言是不确定的 检查任何条件。

如果您不希望结果包含在内,请删除对Assert.Inconclusive 的调用:)

【讨论】:

我的观点是数学上的,从商业角度来看,它肯定不是不确定的,而是结论性的,因为它是真的:) Assert.Inconclusive Method 表示一个断言不能被证明为真或假。 根据msdn.microsoft.com/en-us/library/…【参考方案4】:

自动 UnitTest 由 VS 生成,并告诉您创建一些操作进行比较。如果您评论最后一个 Assert 命令,您将获得带有绿色标记的“通过”,但您没有对其进行测试。 您需要,如评论中的“初始化为适当的值”和最后一个断言“验证此测试方法的正确性”。 初始化预期值和实际值的来源 例如,Expected 是函数 Add(x,y) 的期望值,其中 x=2 和 y=3。实际价值应该来自功能。在这种情况下:

// Sample - Start
Expected = 2+3;
Actual = Add(2,3);
Assert.AreEqual(expected, actual);
// Sample - End

希望它有所帮助,我为此打断了几颗牙齿...... ;-)

【讨论】:

以上是关于Visual Studio 单元测试:为啥在测试相同的浮点值时测试运行不确定?的主要内容,如果未能解决你的问题,请参考以下文章

Visual studio 2013安装及单元测试

解决visual studio不能发现单元测试无法运行单元测试的方法

无法在 Visual Studio 2013 中运行单元测试

如何在 Visual Studio 2005 中进行单元测试?

单元测试 - 扩展 Visual Studio 单元测试类型 - 不工作

在Visual Studio2015中使用单元测试