F#开发和单元测试?

Mat*_*ias 104 tdd f# unit-testing functional-programming

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

到目前为止,我用F#过程中一直写一些功能,和他们一起玩与交互式控制台,直到我在"合理"确保他们的工作,并调整与合并.这适用于像欧拉项目这样的小规模问题,但我无法想象以这种方式构建大的东西.

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

Ray*_*gus 74

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

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

Matthew Podwysocki写了一篇关于函数式语言单元测试的精彩系列文章.Bob大叔还写了一个发人深省的文章在这里.

  • 我还开发了(并且正在积极开发)一个名为Unquote的F#特定单元测试库:http://code.google.com/p/unquote/.它允许您使用F#Quotations将测试断言编写为普通的,静态检查的F#布尔表达式,并自动生成不错的测试失败消息.它可以免费配置,对xUnit.net和NUnit都提供特殊支持,并且通常支持任何基于异常的单元测试框架.它甚至可以在FSI会话中使用,允许从交互式测试到正式测试套件的无缝迁移. (9认同)

Dav*_*man 22

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

open NUnit.Framework

[<TestFixture>]
type myFixture() = class

    [<Test>]
    member self.myTest() =
       //test code

end
Run Code Online (Sandbox Code Playgroud)

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

  • 在阅读了其他回复之后,我试试了FSUnit,我认为这很棒.它适用于TestDriven.Net(和NUnit一样),鼓励采用流畅的方式编写自我记录测试,并且正如Ray所说,"更多的是在F#语言中".对于21行代码来说还不错!(以及一些布局/命名建议).两个快速说明:1.预编译的FSUnit DLL对我不起作用.从源代码构建(FsUnit.NUnit-0.9.0.fs)修复了问题.2. TestDriven.Net无法识别看起来像这样的`\`的TextFixture名称.使用双刻度形式的测试名称被识别. (4认同)

pri*_*mus 15

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

FsCheck CodePlex页面

FsCheck作者页面


Mar*_*ann 11

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

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

.NET的主要优势之一是跨语言功能.我知道我会尽快写F#的生产代码,但我的计划是编写单元测试在C#我的方式缓解到什么对我来说是一个新的语言.通过这种方式,我还可以测试我在F#中编写的内容是否与C#(以及其他.NET语言)兼容.

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

  • @ScottNimrod我不建议花时间和/或付钱来查看完整的马克PS课程 - 它会以最高的效率将它们全部拼凑在一起.虽然它可能适用于或不适用于您的特定需求,但"F#中的功能架构"也会连接很多点,也应该被强烈考虑. (3认同)
  • 你的计划如何进展?使用c#代码测试f#代码很容易吗?我开始学习f#,我的计划是用f#编写项目的一部分,我也有同样的想法:用c#编写单元测试用于f#. (2认同)

Ade*_*ler 11

正如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) 
Run Code Online (Sandbox Code Playgroud)


Shd*_*dNx 7

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

  • 要清楚,如果使用FsUnit,您仍将拥有TestFixtures和Test成员.你没有的是标准的Assert.X调用.FsUnit只是为你提供了一个围绕NUnit这部分的包装器,它使它更适合在F#语言中使用. (4认同)