【问题标题】:F# Assert.AreEquals fails with two literalsF# Assert.AreEquals 因两个文字而失败
【发布时间】:2014-10-01 13:20:42
【问题描述】:

我有以下单元测试:

open System
open System.Collections.Generic
open Microsoft.VisualStudio.TestTools.UnitTesting

[<TestClass>]
type Test_Spectra () =

    let standard = new Standard1()

    [<TestMethod>]
    member x.LightTransmittance () =

        let input = Test_Spectra.TestSprectra1
        let expected = 0.32728222797751
        let actual = standard.LightTransmittance(input)

        Assert.AreEqual(expected, actual)

当我运行单元测试时它失败了,但是“预期”和“实际”的值是相等的:

Expected 和 Actual 分别被推断为 float 和 double,但我的印象是 float 只是 double 的简写。 这有什么解释吗?

编辑 根据@Gustavo 的评论,我已将最后一行更改为:

Assert.AreEqual(expected, actual, 0.000000000000001)

测试通过了。

【问题讨论】:

  • 值可能略有不同,因为浮点数最好使用增量进行比较。试试这个重载msdn.microsoft.com/en-us/library/ms243458.aspx
  • 感谢@Gustavo,我使用了 16.0 的 delta 版并且测试通过了。
  • 如果您的实际值
  • 酷。添加为答案。

标签: unit-testing f#


【解决方案1】:

浮点值的相等性很棘手,因为小的舍入差异就足以导致不等式。

当至少其中一个数字来自计算时,使用相等来比较代码中的两个浮点数通常不是一个好主意。这同样适用于单元测试。

你通常做的是定义你的容忍度并使用比较,而不是相等。

    let input = Test_Spectra.TestSprectra1
    let expected = 0.32728222797751
    let actual = standard.LightTransmittance(input)

    let tolerance = 0.000000000000001

    Assert.AreEqual(expected, actual, tolerance)

【讨论】:

    【解决方案2】:

    对于 F#,advantages of unquote 很难忽略。

    例如,如果您想编写类似于@Gustavo 的答案的内容,您可以使用以下内容:

    // In helpers somewhere or I'm sure some lib has relevant functions
    let inline equalsWithinTolerance x tol y = abs(x-y) < tol
    
    test <@ expected |> equalsWithinTolerance .000001 actual @>
    
    let inline (~=) x = equalsWithinTolerance x .00000001
    test <@ expected ~= actual @>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多