首页 文章

F#开发和单元测试?

提问于
浏览
101

我刚开始使用F#,这是我的第一个功能语言 . 我一直在使用C#进行准独家工作,并且很享受F#引导我重新思考如何编写代码 . 我觉得有点迷惑的一个方面是编写代码的过程发生了变化 . 我现在已经在C#中使用TDD多年了,非常感谢有单元测试知道我在哪里 .

到目前为止,我使用F#的过程是编写一些函数,使用交互式控制台与它们一起玩,直到我“合理地”确定它们的工作,并进行调整和组合 . 这适用于像欧拉项目这样的小规模问题,但我无法想象以这种方式构建大的东西 .

人们如何进行单元测试并为F#程序构建测试套件?是否有相当于TDD?任何指针或想法都表示赞赏 .

7 回答

  • 21

    测试驱动的开发人员应该在F#这样的函数式语言中感到宾至如归:提供确定性可重复结果的小函数非常适合单元测试 . F#语言中还有一些功能可以帮助编写测试 . 举个例子,Object Expressions . 您可以非常轻松地为将输入作为接口类型的函数编写伪造 .

    如果有的话,F#是一流的面向对象语言,您可以使用在C#中执行TDD时使用的相同工具和技巧 . 还有一些用于F#编写或专门用于F#的测试工具:

    Matthew Podwysocki用函数式语言编写了一篇关于单元测试的精彩内容 . 鲍勃叔叔还撰写了一篇发人深省的文章here .

  • 10

    我使用NUnit,它不会让我觉得难以阅读或繁琐的写作:

    open NUnit.Framework
    
    [<TestFixture>]
    type myFixture() = class
    
        [<Test>]
        member self.myTest() =
           //test code
    
    end
    

    由于我的代码是F#和其他.Net语言的混合,我喜欢这样的事实:我在F#和C#中以基本相同的方式和类似的语法编写单元测试 .

  • 10

    看看 FsCheck ,一个F#的自动测试工具,基本上是Haskell的QuickCheck的一个端口 . 它允许您以函数或方法应满足的属性的形式提供程序的规范,并且FsCheck测试属性在大量随机生成的情况下保存 .

    FsCheck CodePlex Page

    FsCheck Author Page

  • 72

    正如dglaubman建议您可以使用NUnit . xUnit.net也为此提供支持,并与TestDriven.net配合良好 . 代码看起来类似于NUnit测试,但没有要求将测试包装在包含类型中 .

    #light
    
    // Supply a module name here not a combination of module and namespace, otherwise
    // F# cannot resolve individual tests nfrom the UI.
    module NBody.DomainModel.FSharp.Tests
    
    open System
    open Xunit
    
    open Internal
    
    [<Fact>]
    let CreateOctantBoundaryReordersMinMax() =
        let Max = VectorFloat(1.0, 1.0, 1.0)
        let Min = VectorFloat(-1.0, -1.0, -1.0)
    
        let result = OctantBoundary.create Min Max
    
        Assert.Equal(Min, result.Min)     
        Assert.Equal(Max, result.Max)
    
  • 14

    我认为这是一个非常有趣的问题,我自己也很想知道 . 到目前为止,我的想法只是思想,所以请把它们当作它们 .

    我认为自动化测试套件的安全网是一种非常有 Value 的资产,不管它如何引人注目,因此我计划继续编写单元测试,就像我一直以来所做的那样 .

    .NET的主要优势之一是跨语言功能 . 我知道我很快就会编写F# 生产环境 代码,但我的计划是用C#编写单元测试以简化我对新语言的使用 . 通过这种方式,我还可以测试我在F#中编写的内容是否与C#(以及其他.NET语言)兼容 .

    通过这种方法,我了解到F#的某些功能我只能在我的F#代码中内部使用,但不作为我的公共API的一部分公开,但我会接受,就像我今天接受某些事情一样C#允许我表达(如 uint )不符合CLS,因此我不使用它们 .

  • 0

    你可以看一下FSUnit - 虽然我还没有使用它,但值得一试 . 当然比在F#中使用例如(本机)NUnit更好 .

  • 6

    虽然参加派对有点晚了,但我还是喜欢欢迎Mathias加入F#(迟到总比没有好);以及你喜欢Expecto的钟声

    Expecto有一些您可能喜欢的功能:

    整个

    • F#语法,测试为值;写简单的F#来生成测试

    • 使用内置的Expect模块或Unquote之类的外部库进行断言

    • 默认情况下进行并行测试

    • 测试您的Hopac代码或异步代码; Expecto始终是异步的

    • 可通过Logary Facade进行可插入日志记录和指标;轻松编写适用于构建系统的适配器,或使用计时机制构建测试执行时间的InfluxDB Grafana仪表板

    • 内置对BenchmarkDotNet的支持

    • Build 支持为FsCheck;使用生成/随机数据构建测试或构建对象的不变模型's/actor' s状态空间变得容易

    open Expecto
    
    let tests =
      test "A simple test" {
        let subject = "Hello World"
        Expect.equal subject "Hello World" "The strings should equal"
      }
    
    [<EntryPoint>]
    let main args =
      runTestsWithArgs defaultConfig args tests
    

    https://github.com/haf/expecto/

相关问题