F#开发和unit testing?

我刚刚开始使用F#,这是我的第一个function语言。 我一直准C#工作,并且非常喜欢F#如何让我重新思考如何编写代码。 我发现有一点让人迷惑,就是编写代码的过程发生了变化。 我已经在C#中使用了TDD多年,并且非常感谢有unit testing来知道我在哪里。

到目前为止,我用F#编写的过程一直是编写一些函数,使用交互式控制台与他们一起玩,直到我“合理地”确定他们工作,并调整和合并。 这在欧拉项目这样的小规模问题上效果很好,但是我无法想象以这样的方式构build大的东西。

人们如何进行unit testing并为F#程序构buildtesting套件? 是否有相当于TDD? 任何指针或想法赞赏。

testing驱动的开发人员应该像使用F#这样的函数式语言感到自在:可以给出确定性可重复结果的小函数完全适合于unit testing。 F#语言中还有一些function可以帮助编写testing。 以对象expression式为例。 你可以很容易地写入function的假货作为他们的input接口types。

如果有的话,F#是一stream的面向对象语言,您可以使用在C#中使用TDD时使用的相同的工具和技巧。 还有一些testing工具是专门为F#编写的:

  • NaturalSpec
  • FsCheck
  • FsTest
  • FsUnit

Matthew Podwysocki写了一篇function语言unit testing的系列文章。 鲍伯叔叔还在这里写了一篇发人深思的文章。

我使用NUnit,它不会让我难以阅读或繁重写:

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

由于我的代码是F#和其他.Net语言的混合,所以我喜欢我在F#和C#中以基本相同的方式编写unit testing并使用类似的语法来编写testing。

看看F#的自动testing工具FsCheck ,基本上就是Haskell的QuickCheck的一个端口。 它允许您以函数或方法应该满足的属性的forms提供程序的规范,并且FsCheck会testing这些属性在大量随机生成的情况下是否存在。

FsCheck CodePlex页面

FsCheck作者页面

正如dglaubmanbuild议你可以使用NUnit。 xUnit.net也为此提供了支持,并与TestDriven.net一起使用 。 该代码看起来类似于NUnittesting,但不需要将testing封装在包含types中。

 #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) 

我觉得这是一个非常有趣的问题,我自己也想了很多。 我的想法到目前为止只是想法,所以要把它们看成是什么。

我认为自动化testing套件的安全networking是一种无法放弃的资产,然而,鉴于交互式控制台的可能性,我打算继续编写unit testing。

.NET的主要优势之一就是跨语言function。 我知道我将尽快编写F#生产代码,但是我的计划是在C#中编写unit testing,以便让我更容易理解新语言。 通过这种方式,我也可以testing我在F#中编写的代码是否与C#(以及其他.NET语言)兼容。

通过这种方法,我明白F#的某些特性只能在我的F#代码中内部使用,而不能作为公共API的一部分公开,但我会接受的,就像我今天接受的那样,有某些东西C#允许我expression(如uint )不符合CLS,所以我不使用它们。

你可以看一下FSUnit – 尽pipe我还没有使用过它,可能值得一试。 当然,比在F#中使用(native)NUnit更好。